小白學習Java第六天,Collection集合, Iterator迭代器,泛型

一、Collection集合

1、集合:集合是java中提供的一種容器,可以用來存儲多個數據。
2、集合和數組既然都是容器,它們有什麼區別呢?
數組的長度是固定的。集合的長度是可變的。
數組中存儲的是同一類型的元素,可以存儲基本數據類型值。集合存儲的都是對象。而且對象的類型可以不一致。在開發中一般當對象多的時候,使用集合進行存儲。
3、集合按照其存儲結構可以分爲兩大類,分別是單列集合java.util.Collection和雙列集合java.util.Map
Collection:單列集合類的根接口,用於存儲一系列符合某種規則的元素,它有兩個重要的子接口,分別是java.util.Listjava.util.Set。其中,List的特點是元素有序、元素可重複。Set的特點是元素無序,而且不可重複。List接口的主要實現類有java.util.ArrayListjava.util.LinkedListSet接口的主要實現類有java.util.HashSetjava.util.TreeSet
具體如圖所示:
在這裏插入圖片描述
4、List接口介紹:
1)它是一個元素存取有序的集合。例如,存元素的順序是11、22、33。那麼集合中,元素的存儲就是按照11、22、33的順序完成的)。
2)它是一個帶有索引的集合,通過索引就可以精確的操作集合中的元素(與數組的索引是一個道理)。
3)集合中可以有重複的元素,通過元素的equals方法,來比較是否爲重複的元素。
5、ArrayList集合。java.util.ArrayList集合數據存儲的結構是數組結構。元素增刪慢,查找快,由於日常開發中使用最多的功能爲查詢數據、遍歷數據,所以ArrayList是最常用的集合。
許多程序員開發時非常隨意地使用ArrayList完成任何需求,並不嚴謹,這種用法是不提倡的。
6、LinkedList集合。java.util.LinkedList集合數據存儲的結構是鏈表結構。方便元素添加、刪除的集合。
LinkedList是一個雙向鏈表,如下圖:
在這裏插入圖片描述
LinkedList是List的子類,List中的方法LinkedList都是可以使用,這裏就不做詳細介紹,我們只需要瞭解LinkedList的特有方法即可。在開發時,LinkedList集合也可以作爲堆棧,隊列的結構使用。(瞭解即可)
7、Set接口介紹:
java.util.Set接口和java.util.List接口一樣,同樣繼承自Collection接口,它與Collection接口中的方法基本一致,並沒有對Collection接口進行功能上的擴充,只是比Collection接口更加嚴格了。與List接口不同的是,Set接口中元素無序,並且都會以某種規則保證存入的元素不出現重複。
Set集合有多個子類,這裏我們介紹其中的java.util.HashSetjava.util.LinkedHashSet這兩個集合。
8、HashSet集合。HashSet是根據對象的哈希值來確定元素在集合中的存儲位置,因此具有良好的存取和查找性能。保證元素唯一性的方式依賴於:hashCodeequals方法。HashSet集合存儲數據的結構(哈希表)。
哈希值:是一個十進制的整數,由系統隨機給出(就是對象的地址值,是一個邏輯地址,是模擬出來得到地址,不是數據實際存儲的物理地址)。 在Object類有一個方法,可以獲取對象的哈希值。 int hashCode() 返回該對象的哈希碼值。hashCode方法的源碼:public native int hashCode(); 其中 native:代表該方法調用的是本地操作系統的方法。
9、HashS集合內部如何實現?
JDK1.8之前,哈希表底層採用數組+鏈表實現,即使用鏈表處理衝突,同一hash值的鏈表都存儲在一個鏈表裏。但是當位於一個桶中的元素較多,即hash值相等的元素較多時,通過key值依次查找的效率較低。而JDK1.8中,哈希表存儲採用數組+鏈表+紅黑樹實現,當鏈表長度超過閾值(8)時,將鏈表轉換爲紅黑樹,這樣大大減少了查找時間。
簡單的來說,哈希表是由數組+鏈表+紅黑樹(JDK1.8增加了紅黑樹部分)實現的,如下圖所示。
在這裏插入圖片描述
在這裏插入圖片描述
總而言之,JDK1.8引入紅黑樹大程度優化了HashMap的性能,那麼對於我們來講保證HashSet集合元素的唯一,其實就是根據對象的hashCode和equals方法來決定的。如果我們往集合中存放自定義的對象,那麼保證其唯一,就必須複寫hashCode和equals方法建立屬於當前對象的比較方式。
10、可變參數。
可變參數:是JDK1.5之後出現的新特性。
使用前提:
當方法的參數列表數據類型已經確定,但是參數的個數不確定,就可以使用可變參數。
使用格式:定義方法時使用
修飾符 返回值類型 方法名(數據類型…變量名){}
可變參數的原理:
可變參數底層就是一個數組,根據傳遞參數個數不同,會創建不同長度的數組,來存儲這些參數。
傳遞的參數個數,可以是0個(不傳遞),1,2…多個。
代碼演示:

public class ChangeArgs {
    public static void main(String[] args) {
        int[] arr = { 1, 4, 62, 431, 2 };
        int sum = getSum(arr);
        System.out.println(sum);
        //  6  7  2 12 2121
        // 求 這幾個元素和 6  7  2 12 2121
        int sum2 = getSum(6, 7, 2, 12, 2121);
        System.out.println(sum2);
    }

    /*
     * 完成數組  所有元素的求和 原始寫法
     
      public static int getSum(int[] arr){
        int sum = 0;
        for(int a : arr){
            sum += a;
        }
        
        return sum;
      }
    */
    //可變參數寫法
    public static int getSum(int... arr) {
        int sum = 0;
        for (int a : arr) {
            sum += a;
        }
        return sum;
    }
}

11、說到排序,簡單的說就是兩個對象之間比較大小,那麼在JAVA中提供了兩種比較實現的方式,一種是比較死板的 採用 java.lang.Comparable 接口去實現,一種是靈活的當我需要做排序的時候在去選擇的 java.util.Comparator 接口完成。
12、簡述Comparable和Comparator兩個接口的區別?
Comparable:強行對實現它的每個類的對象進行整體排序。這種排序被稱爲類的自然排序,類的compareTo方法被稱爲它的自然比較方法。只能在類中實現compareTo()一次,不能經常修改類的代碼實現自己想要的排序。實現此接口的對象列表(和數組)可以通過Collections.sort(和Arrays.sort)進行自動排序,對象可以用作有序映射中的鍵或有序集合中的元素,無需指定比較器。
Comparator強行對某個對象進行整體排序。可以將Comparator 傳遞給sort方法(如Collections.sort或 Arrays.sort),從而允許在排序順序上實現精確控制。還可以使用Comparator來控制某些數據結構(如有序set或有序映射)的順序,或者爲那些沒有自然順序的對象collection提供排序。

 Collections.sort(list02, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
                //按照年齡升序排序
                int result =  o1.getAge()-o2.getAge();
                //如果兩個人年齡相同,再使用姓名的第一個字比較
                if(result==0){
                    result =  o1.getName().charAt(0)-o2.getName().charAt(0);
                }
                return  result;
            }

        });
public class Person implements Comparable<Person>{
    private String name;
    private int age;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    //重寫排序的規則
    @Override
    public int compareTo(Person o) {
        //return 0;//認爲元素都是相同的
        //自定義比較的規則,比較兩個人的年齡(this,參數Person)
        //return this.getAge() - o.getAge();//年齡升序排序
        return o.getAge() - this.getAge();//年齡升序排序
    }
}

可以說一個是自已完成比較,一個是外部程序實現比較的差別而已。

二、Iterator迭代器

1、在程序開發中,經常需要遍歷集合中的所有元素。針對這種需求,JDK專門提供了一個接口java.util.IteratorIterator接口也是Java集合中的一員,但它與CollectionMap接口有所不同,Collection接口與Map接口主要用於存儲元素,Iterator主要用於迭代訪問(即遍歷)Collection中的元素,因此Iterator對象也被稱爲迭代器。
2、當遍歷集合時,首先通過調用t集合的iterator()方法獲得迭代器對象,然後使用hashNext()方法判斷集合中是否存在下一個元素,如果存在,則調用next()方法將元素取出,否則說明已到達了集合末尾,停止遍歷元素。
Iterator迭代器對象在遍歷集合時,內部採用指針的方式來跟蹤集合中的元素,接下來通過一個圖例來演示Iterator對象迭代元素的過程:
在這裏插入圖片描述
3、增強for:增強for循環(也稱for each循環)是JDK1.5以後出來的一個高級for循環,專門用來遍歷數組和集合的。它的內部原理其實是個Iterator迭代器,所以在遍歷的過程中,不能對集合中的元素進行增刪操作。
格式:

for(元素的數據類型  變量 : Collection集合or數組){ 
  	//寫操作代碼
}

它用於遍歷Collection和數組。通常只進行遍歷元素,不要在遍歷的過程中對集合元素進行增刪操作。
遍歷數組:

public class NBForDemo1 {
    public static void main(String[] args) {
		int[] arr = {3,5,6,87};
       	//使用增強for遍歷數組
		for(int a : arr){//a代表數組中的每個元素
			System.out.println(a);
		}
	}
}

遍歷集合:

public class NBFor {
    public static void main(String[] args) {        
    	Collection<String> coll = new ArrayList<String>();
    	coll.add("小河神");
    	coll.add("老河神");
    	coll.add("神婆");
    	//使用增強for遍歷
    	for(String s :coll){//接收變量s代表 代表被遍歷到的集合元素
    		System.out.println(s);
    	}
	}
}

三、泛型

1、泛型:可以在類或方法中預支地使用未知的類型。
2、使用泛型的好處:

  • 將運行時期(run運行的時候)的ClassCastException,轉移到了編譯時期(寫代碼的時候)變成了編譯失敗。
  • 避免了類型強轉的麻煩,存儲什麼類型,取出就是什麼類型,不用做類型轉換。
    在這裏插入圖片描述
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章