java中Collection、泛型

1.1 集合概述

1.什麼是集合:

  • 一個用來存儲多個元素的容器。

2.數組和集合的區別:

  • 數組:長度固定,可以存儲基本數據類型  ,也可以存儲引用數據類型。
  • 集合:長度可變,只能存儲引用數據類型,如果存儲基本數據類型則需要使用對應的包裝類。

3.集合的分類:

  • 單列集合(Collection):每次存儲元素時只存儲一個元素。
  • 雙列集合(Map):每次存儲元素時要 存儲兩個元素。

1.2 Collection集合體系 

  • Collection:父接口  所有單列集合的父類
  • List:子接口
  1. ArrayList:實現類
  2. LinkedList:實現類
  3. Vector:實現類
  • Set:子接口
  1. HashSet:實現類
  2. LinkedHashSet:實現類

  •  其中,橙色框裏寫的都是接口類型,而藍色框裏填寫的都是具體的實現類。
  • 集合本身是一個工具,它存放在Java.util包中。在Collection接口定義着單列集合框架中最共性的內容。

1.3 Collection常用方法 

  • public boolean add(E e):添加元素,添加成功返回true,否則false。
  • public void clear():將集合元素清空。
  • boolean remove(E e)
  1. 刪除指定元素,刪除成功返回true,否則false。
  2. 如果有多個相同的元素,默認只會刪除第一個
  • boolean contains(E e):判斷集合是否包含指定元素,包含返回true,否則false。
  • public boolean isEmpty():判斷集合是否爲空(元素個數是否爲0),是返回true,否則false。
  • public int size():獲得元素的個數。
  • public Object[] toArray()
  1. 將集合中的元素添加到數組返回
  2. 集合轉數組
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

public class CollectionDemo01 {
    public static void main(String[] args) {
        //創建集合對象
        Collection<String> coll=new ArrayList<String>();

        //添加元素
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");

        System.out.println(coll);
        //刪除元素
        System.out.println(coll.remove("aaa"));// true
        System.out.println(coll);

        //判斷集合中是否包含元素
        System.out.println(coll.contains("eeee"));//false

        //集合轉數組
        Object [] objs=coll.toArray();
        //輸出數組中的元素
        System.out.println(Arrays.toString(objs));//[bbb, ccc, ddd]

        //清空集合元素
        coll.clear();
        System.out.println(coll);//[]

        //判斷集合是否爲空
        System.out.println(coll.isEmpty());//true
    }
}

2.1 迭代器概述 

1.什麼是迭代器?

  • 一個用來遍歷集合的對象,該對象實現了Iterator接口
  • 對Collection進行遍歷的迭代器

2.如何獲得迭代器對象?

  • 通過集合對象調用該方法:Iterator<E> iterator()獲得迭代器對象。

3. Iterator接口常用方法?

  • boolean hasNext() 判斷是否有下一個元素,有返回true,否則false
  • E next() 先將指針下移指向下一個元素,並將當前指針指向位置的元素作爲返回值返回。 

2.2 Iterator示例代碼  

import java.util.ArrayList;
import java.util.Iterator;

public class IteratorDemo01 {
    public static void main(String[] args) {
        //創建集合對象
        ArrayList<String> list=new ArrayList<>();

        //添加元素
        list.add("aa");
        list.add("bb");
        list.add("cc");
        list.add("dd");

        //使用普通for循環遍歷
        for (int i = 0; i < list.size(); i++) {
            System.out.println(list.get(i));
        }

        System.out.println("--------------------");
        //獲得迭代器對象
        Iterator<String> it=list.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
}

2.3 迭代器的好處

  • 屏蔽了衆多集合的內部實現,對外提供統一的遍歷方式。
  • 所有的單列集合都可以使用迭代器進行遍歷。

2.4 迭代器的注意事項

  • hasNext方法僅僅是判斷是否有下一個元素,不會移動指針位置。
  • hasNext方法和next方法必須成對出現,調用一次hasNext就對應一次next方法。
  • 使用迭代器遍歷集合時不能對集合進行增刪操作,否則會拋出異常。
  • java.util.ConcurrentModificationException: 併發修改異常 
  1. 在使用迭代器遍歷集合的過程中對集合元素進行了增刪操作,則會拋出該異常。

3.1 增強for概述

1.增強for概述

  • JDK1.5新特性
  • 專門用來遍歷集合和數組
  • 本質:迭代器

2.增強for格式

  • for(數據類型   變量名:數組名或集合名){ //循環體}

3.2 增強for遍歷數組

public class ForEachDemo01 {
    public static void main(String[] args) {
        //定義數組
        int [] arr={1,2,3,4,5,6};

        //使用增強for遍歷數組
        for(int num: arr){
            System.out.println(num);
        }
    }
}

 3.3 增強for遍歷集合

import java.util.ArrayList;

/*
    增強for遍歷集合:存儲自定義對象
 */
public class ForEachDemo03 {
    public static void main(String[] args) {
        // 創建集合對象
        ArrayList<Student> list = new ArrayList<>();
        // 添加學生對象
        list.add(new Student("小澤", 20));
        list.add(new Student("小蒼", 24));
        list.add(new Student("小波", 26));
        list.add(new Student("小武", 28));
        // 使用增強for
        for (Student stu : list) {
            System.out.println(stu);
            // 修改姓名
            stu.setName("lily");
        }
        System.out.println("----------");
        // 使用增強for
        for (Student stu : list) {
            System.out.println(stu);
        }
    }
}

4.1 泛型在集合中的使用

  • 創建集合同時指定集合存儲的數據類型
  • 指定數據類型時,要麼指定左邊,要麼兩邊都執行相同的數據類型
  • 在JDK1.7之前,必須兩邊都要指定並且要相同的數據類型
  • JDK1.7之後,指定左邊即可
  • 在泛型中沒有多態的概念

4.2 泛型在集合中使用的好處

  • 將運行時錯誤轉換爲編譯期錯誤,增強了集合的安全性。
  • 省去了數據類型強制轉換的麻煩。
  •  示例代碼
import java.util.ArrayList;
import java.util.Collection;

public class CollectionDemo04 {
    public static void main(String[] args) {
        //創建集合對象
        ArrayList<String> list=new ArrayList<String>();

        list.add("aa");
        list.add("bb");
        list.add("cc");

        for(String  str:list){
            System.out.println(str.length());
        }
    }
}

4.3 泛型的定義與使用

1.泛型的概述

  • JDK1.5新特性。 
  • 泛型可以使用在方法上,上,接口上。 
  • 泛型變量可以理解爲是某種數據類型的佔位符。
  • 泛型變量還可以理解爲是某種數據類型的變量。 
  • 泛型變量的命名規則:只要是合法的標識符就可以,一般使用一個大寫字母表示 

   a.常用的泛型變量名有:T type E element K key V value 

2.泛型方法的概念

  • 在定義方法時定義了泛型變量的方法就是泛型方法 。

3.泛型方法的定義格式

  • 修飾符 <T> 返回值類型 方法名(參數列表){} 

4.泛型方法的注意事項 

  • 泛型變量的具體數據類型是由調用者調用方法時傳參決定。 
  •  泛型變量的具體數據類型不能是基本數據類型,如果要使用基本數據類型則需要使用對應的包裝類類型。
  • 泛型方法示例代碼1
public class Demo01 {
    public static void main(String[] args) {
        Integer in=test(456);
        String str=test("bcd");
        Student stu=test(new Student());
        Double d=test(0.5);
        int age=10;
        System.out.println(age);

    }
    //泛型方法
    public static <T> T test(T param){
        T a=null;
        return a;
    }
}
  •  泛型方法示例代碼2
/*
     定義一個數組工具類MyArrays ,提供兩個成員方法,方法參數接收一個任意類型的數組  
     一個方法的功能是將數組的元素反轉.   
      一個方法的功能是將數組的元素拼接成一個字符串返回。    
     字符串格式:"[1,2,3,4,5]" 
 */
public class MyArrays{

    /*
     使用泛型方法實現:方法參數接收一個任意類型的數組
      一個方法的功能是將數組的元素反轉.
     */
    public static <T> void reverse(T[] arr){
        for(int i=0,j=arr.length-1;i<j;i++,j--){
            T temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }

    /*
        使用泛型方法:定義一個方法的功能:將數組的元素拼接成一個字符串返回。
        字符串格式:"[1,2,3,4,5]"
     */
    public static <T> String toString(T [] arr){
        //創建可變字符串
        StringBuilder sb=new StringBuilder("[");
        //遍歷數組
        for(T t:arr){
            sb.append(t).append(",");
        }
        //刪除最後一個元素
        sb.deleteCharAt(sb.length()-1);
        sb.append("]");
        return sb.toString();
    }
}

4.4 泛型類

1. 泛型類概述

  • 在定義類的同時定義了泛型變量的類。 

2.泛型類的定義格式 

  • class 類名<T>{ // 在該類中可以將泛型變量T當成一種數據類型使用。 } 

3.泛型類的注意事項 

  • 泛型類泛型變量的具體數據類型是在創建該類對象時由創建者指定。 
  • 如果創建泛型類對象時沒有指定泛型變量的具體數據類型,則默認是Object 
  •  靜態方法不能使用類上定義的泛型變量,如果該方法中要使用泛型變量,則需要將該定義爲泛型方法。
  • 示例代碼 
public class MyArrays<T>{

    /*
      方法參數接收一個任意類型的數組
      一個方法的功能是將數組的元素反轉.
     */
    public  void reverse(T[] arr){
        for(int i=0,j=arr.length-1;i<j;i++,j--){
            T temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }

    /*
        將數組的元素拼接成一個字符串返回。
        字符串格式:"[1,2,3,4,5]"
     */
    public  String toString(T [] arr){
        //創建可變字符串
        StringBuilder sb=new StringBuilder("[");
        //遍歷數組
        for(T t:arr){
            sb.append(t).append(",");
        }
        //刪除最後一個元素
        sb.deleteCharAt(sb.length()-1);
        sb.append("]");
        return sb.toString();
    }
}
//泛型類基本使用
public class Demo {
    public static void main(String[] args) {
        //定義字符串數組
        String[] strs = {"a", "b", "c"};

        //創建MyArrays對象
        MyArrays<String> myArrays01=new MyArrays<>();
        myArrays01.reverse(strs);
        System.out.println(myArrays01.toString(strs));//[c,b,a]

        //創建MyArrays對象
        MyArrays<Integer> myArrays02=new MyArrays<>();
        //創建整型數組
        Integer[] arr={3,4,5,6,7,7};
        myArrays02.reverse(arr);
        System.out.println(myArrays02.toString(arr));//[7,7,6,5,4,3]

        //創建MyArrays對象:不指定泛型變量的具體數據類型
        MyArrays myArrays03=new MyArrays();
    }
}

5.1 泛型接口

1. 泛型接口的概念

  • 在定義接口的同時定義了泛型變量的接口 

2.泛型接口的定義格式 

  • interface 接口名<T>{ // 可以將泛型變量T當成一種數據類型使用 } 

3.泛型接口的實現方式 

  • 方式1:實現接口的同時指定泛型變量的具體數據類型。(不夠靈活) 
  •  方式2:實現接口的時不指定泛型變量的具體數據類型,那麼此時需要將該實現類定義爲泛型類 ,由使用者創建實現類對象時指定泛型變量的數據類型。(推薦使用)
  • 泛型接口示例代碼 
/*
   分層開發:
   1.表現層
   2.業務層
   3.數據訪問層:直接和數據庫打交道,對數據庫進行增刪改查操作。
 */
public interface Dao<T> {
    //增
    public void save(T t);
    //刪
    public void delete(int id);
    //改
    public void update(T t);
    //查
    public T find(int id);
}
/*
    方式1:實現接口的同時指定泛型變量的具體數據類型。
 */
public class ProductDao implements Dao<Product> {
    @Override
    public void save(Product product) {
        System.out.println("增加產品");
    }

    @Override
    public void delete(int id) {

    }

    @Override
    public void update(Product product) {

    }

    @Override
    public Product find(int id) {
        return null;
    }
}
/*
    方式1:實現接口的同時指定泛型變量的具體數據類型。
 */
public class StudentDao implements Dao<Student> {
    @Override
    public void save(Student student) {
        System.out.println("保存學生信息");
    }

    @Override
    public void delete(int id) {
        System.out.println("刪除學生信息");
    }

    @Override
    public void update(Student student) {
        System.out.println("更新學生信息");
    }

    @Override
    public Student find(int id) {
        System.out.println("查找學生信息");
        return null;
    }
}
/*
    實現接口的時不指定泛型變量的具體數據類型,那麼此時需要將該實現類定義爲泛型類,
    由使用者創建實現類對象時指定泛型變量的數據類型。
 */
public  class BaseDao<T> implements Dao<T> {
    @Override
    public void save(T t) {

    }

    @Override
    public void delete(int id) {

    }

    @Override
    public void update(T t) {

    }

    @Override
    public T find(int id) {
        return null;
    }
}
public class Demo {
    public static void main(String[] args) {
        //創建學生對象
        Student stu=new Student();

        //創建StudentDao對象
        StudentDao stuDao=new StudentDao();
        stuDao.save(stu);
        stuDao.update(stu);
        stuDao.delete(1);
        stuDao.find(2);

        //創建產品對象
        Product p=new Product();
        //創建ProduceDao對象
        ProductDao pd=new ProductDao();
        pd.save(p);

        // 創建BaseDao對象指定泛型變量是Student
        BaseDao<Student> baseDao=new BaseDao<>();
        baseDao.save(stu);

        // 創建BaseDao對象指定泛型變量是Product
        BaseDao<Product> baseDao2=new BaseDao<>();
        baseDao2.save(p);

    }
}

6.1 泛型上下限

6.1.1 泛型上下限的引入

需求1:

  • 定義一個方法可以接收任意類型的集合對象
  • 集合對象只能存儲Integer或者是Integer的父類數據

需求2:

  • 定義一個方法可以接收任意類型的集合對象
  • 集合對象只能存儲Number或者是Number的子類數據

 6.1.2 泛型上下限的格式

1.泛型的上限

  • 格式:<? extends 類>
  • 意義:只能接收該類型及其子類

2.泛型的下限

  • 格式:<? super類>
  • 意義:只能接收該類型及其父類型
  • 注意事項
  • ? 代表泛型通配符,可以匹配任意的類型。
  • 通配符?不能用在泛型方法、泛型類、泛型接口定義上。
  • 通配符?一般不會單獨使用,一般都會配合泛型上下限使用。
  • ? 不能在方法體中當成一種數據類型使用 

   a.泛型上限

     ? extends Number:可以接收Number或Number子類類型的數據  

   b.泛型下限     

    ? super Integer : 可以接收Integer或Integer父類類型的數據

import java.util.ArrayList;

public class Demo05 {
    public static void main(String[] args) {
        ArrayList<Number> list01=new ArrayList<>();
        ArrayList<Integer> list02=new ArrayList<>();
        ArrayList<Object> list03=new ArrayList<>();
        print01(list01);
        print01(list02);
        print01(list03);

        print02(list01);
        print02(list02);
        //print02(list03);
    }
    /*
        需求2:定義一個方法可以接收任意類型的集合對象
        集合對象只能存儲Number或者是Number的子類數據
     */
    public static void print02(ArrayList<? extends Number> list){

    }
    /*
        需求1:定義一個方法可以接收任意類型的集合對象
        集合對象只能存儲Integer或者是Integer的父類數據
     */
    public static void print01(ArrayList<? super Integer> list){

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章