Java核心知識體系6:集合框架詳解


Java核心知識體系1:泛型機制詳解
Java核心知識體系2:注解機制詳解
Java核心知識體系3:異常機制詳解
Java核心知識體系4:AOP原理和切面應用
Java核心知識體系5:反射機制詳解

1 集合框架圖總覽

image
我們來簡單解讀下上面這個框架圖:

  • 所有集合類都位於java.util包下
  • Iterator是遍歷集合的工具,我們經常通過Iterator迭代器來遍歷集合。我們說Collection依賴於Iterator,是因為Collection的實現類都要實現iterator()函數,返回一個Iterator對象。ListIterator主要作用就是遍歷List。
  • Java的集合類主要由兩個接口派生而出:Collection和Map,作為Java集合框架的根接口,這兩個接口包含了一些子接口和實現類。
  • 集合接口:即圖中的 LinkIterator、List、Set、Queue、SortedMap、SortedMap 6個接口(即短虛線框部分),表示不同集合類型,是集合框架的基礎。
  • 抽象類:即圖中的 AbstractCollection、AbstractList、AbstractSet、AbstractMap、AbstractSequentialList 5個抽象類(長虛線框部分),抽象類只是對集合接口的部分實現,有需要的話可以繼續擴展,完善自定義集合類。
  • 實現類:即圖片中LinkHashMap、TreeMap等8個實現類(實線框部分),主要是對接口的具體實現。
  • Collection 接口包含一組允許重復的對象
  • Set 接口繼承 Collection,但是集合內的元素不重復。Set的實現類有HastSet和TreeSet。HashSet依賴於HashMap,它實際上是通過HashMap實現的;TreeSet依賴於TreeMap,它實際上是通過TreeMap實現的。
  • List 接口繼承 Collection,集合內元素允許重復,但維護了元素的插入順序,所以是個有序隊列。每一個元素都有它的索引。第一個元素的索引值是0。List的實現類有LinkedList, ArrayList, Vector, Stack。
  • Map接口是鍵-值對象頂層接口,下面還包含了一些子接口和實現類。AbstractMap是個抽象類,它實現了Map接口中的大部分API。而HashMap,TreeMap,WeakHashMap都是繼承於AbstractMap。Hashtable雖然繼承於Dictionary,但它實現了Map接口。
  • Set、List和Map是集合的三大類:
    • List:有序集合,集合中元素可重復,訪問元素可以根據元素索引訪問。
    • Set:無序集合,集合中元素不可以重復,訪問集合中的元素只能根據元素自身信息來訪問(因此元素不允許重復)。
    • Map:Key-value模式的鍵值對元素,訪問時根據元素key來讀取對應的value。
  • Arrays和Collections是操作數組、集合的兩個工具類。

完成對上面框架的整體介紹之后,我們接着對每個類別進行詳細的分析。

2 Collection接口

Collection接口是處理對象集合的根接口,其中定義了很多對元素進行操作的方法。Collection接口有兩個主要的子接口List和Set,注意Map不是Collection的子接口,這個要牢記。
Collection接口中的方法如下:
image
其中,有幾個比較常用的方法,比如方法add()添加一個元素到集合中,addAll()將指定集合中的所有元素添加到集合中,contains()方法檢測集合中是否包含指定的元素,toArray()方法返回一個表示集合的數組。

另外,Collection中有一個iterator()函數,它的作用是返回一個Iterator接口。通常,我們通過Iterator迭代器來遍歷集合。ListIterator是List接口所特有的,在List接口中,通過ListIterator()返回一個ListIterator對象。

Collection接口有兩個常用的子接口,下面會詳細介紹。

2.1 List接口

List集合代表一個有序集合,集合中每個元素都有其對應的順序索引。List集合允許使用重復元素,可以通過索引來訪問指定位置的集合元素。

List接口繼承於Collection接口,它可以定義一個允許重復的有序集合。因為List中的元素是有序的,所以我們可以通過使用索引(元素在List中的位置,類似於數組下標)來訪問List中的元素,這類似於Java的數組。

List接口為Collection直接接口。List所代表的是有序的Collection,即它用某種特定的插入順序來維護元素順序。用戶可以對列表中每個元素的插入位置進行精確地控制,同時可以根據元素的整數索引(在列表中的位置)訪問元素,並搜索列表中的元素。實現List接口的集合主要有:ArrayList、LinkedList、Vector、Stack。

2.1.1 ArrayList

ArrayList是一個動態數組,也是我們最常用的集合。它允許任何符合規則的元素插入甚至包括null。每一個ArrayList都有一個初始容量(10),該容量代表了數組的大小。隨着容器中的元素不斷增加,容器的大小也會隨着增加。在每次向容器中增加元素的同時都會進行容量檢查,當快溢出時,就會進行擴容操作。所以如果我們明確所插入元素的多少,最好指定一個初始容量值,避免過多的進行擴容操作而浪費時間、效率。

size、isEmpty、get、set、iterator 和 listIterator 操作都以固定時間運行。add 操作以分攤的固定時間運行,也就是說,添加 n 個元素需要 O(n) 時間(由於要考慮到擴容,所以這不只是添加元素會帶來分攤固定時間開銷那樣簡單)。

ArrayList擅長於隨機訪問。同時ArrayList是非同步的。

2.1.2 LinkedList

同樣實現List接口的LinkedList與ArrayList不同,ArrayList是一個動態數組,而LinkedList是一個雙向鏈表。所以它除了有ArrayList的基本操作方法外還額外提供了get,remove,insert方法在LinkedList的首部或尾部。

由於實現的方式不同,LinkedList不能隨機訪問,它所有的操作都是要按照雙重鏈表的需要執行。在列表中索引的操作將從開頭或結尾遍歷列表(從靠近指定索引的一端)。這樣做的好處就是可以通過較低的代價在List中進行插入和刪除操作。

與ArrayList一樣,LinkedList也是非同步的。如果多個線程同時訪問一個List,則必須自己實現訪問同步。一種解決方法是在創建List時構造一個同步的List:
List list = Collections.synchronizedList(new LinkedList(...));

2.1.3 Vector

與ArrayList相似,但是Vector是同步的。所以說Vector是線程安全的動態數組。它的操作與ArrayList幾乎一樣。

2.1.4 Stack

Stack繼承自Vector,實現一個后進先出的堆棧。Stack提供5個額外的方法使得Vector得以被當作堆棧使用。基本的push和pop 方法,還有peek方法得到棧頂的元素,empty方法測試堆棧是否為空,search方法檢測一個元素在堆棧中的位置。Stack剛創建后是空棧。
image

2.2 Set接口

Set是一種不包括重復元素的Collection。它維持它自己的內部排序,所以隨機訪問沒有任何意義。與List一樣,它同樣允許null的存在但是僅有一個。由於Set接口的特殊性,所有傳入Set集合中的元素都必須不同,同時要注意任何可變對象,如果在對集合中元素進行操作時,導致element1.equals(element2)為true,則必定會產生數據沖突的問題。Set接口有三個具體實現類,分別是

  • 散列集HashSet
  • 鏈式散列集LinkedHashSet
  • 樹形集TreeSet

Set是一種不包含重復的元素的Collection,無序,即任意的兩個元素element1和element2都有element1.equals(element2)為false,Set最多可以有一個null元素。需要注意的是,雖然Set中元素沒有順序性,但是元素在set中的位置是由該元素的HashCode決定的,所以具體的位置其實是固定的。

此外需要說明一點,在set接口中的不重復是有特殊要求的。
舉一個例子:對象A和對象B,本來是不同的兩個對象,正常情況下它們是能夠放入到Set里面的,但是如果對象A和B的都重寫了hashcode和equals方法,並且重寫后的hashcode和equals方法是相同的話。那么A和B是不能同時放入到Set集合中去的,也就是Set集合中的去重和hashcode與equals方法直接相關。

為了更好地理解,請看下面的例子:

 private static void setWork() {
        Set<String> set = new HashSet<>();
        set.add("Brand1");
        set.add("Brand2");
        set.add("Brand1");
        System.out.println("Set Size:" + set.size());
        System.out.println("Set Elements:" + set.toString());
		
		//再次添加一個字符串對象 Brand2,然后通過equals方法比較,發現是相等的,所以添加失敗返回false
        boolean result = set.add(new String("Brand2"));
        System.out.println(result);
        System.out.println(set);
    }

執行結果:
Set Size:2
Set Elements:[Brand1, Brand2]
false
[Brand1, Brand2]
可以看出,因為有hashcode和equals方法,用來比較指向的字符串對象所存儲的字符串是否相等,所以第二個Brand1加進去是無效的。
程序通過new關鍵字來創建新的字符串對象Brand2,使用==運算符判斷返回false,使用equals方法比較返回true,所以同樣不能添加到Set集合中,最終還是兩個元素。

2.2.1 HashSet

HashSet 是一個沒有重復元素的集合。它是由HashMap實現的,不保證元素的順序(這里所說的沒有順序是指:元素插入的順序與輸出的順序不一致),而且HashSet允許使用null 元素。HashSet是非同步的,如果多個線程同時訪問一個哈希set,而其中至少一個線程修改了該set,那么它必須保持外部同步。 HashSet按Hash算法來存儲集合的元素,因此具有很好的存取和查找性能。
HashSet的實現方式大致如下,通過一個HashMap存儲元素,元素是存放在HashMap的Key中,而Value統一使用一個Object對象。
HashSet使用和理解中容易出現的誤區:

  • HashSet中存放null值
    HashSet中是允許存入null值的,但是在HashSet中僅僅能夠存入一個null值。
  • HashSet中存儲元素的位置是固定的
    HashSet中存儲的元素的是無序的,這個沒什么好說的,但是由於HashSet底層是基於Hash算法實現的,使用了hashcode,所以HashSet中相應的元素的位置是固定的。
  • 必須小心操作可變對象(Mutable Object)。
    如果一個Set中的可變元素改變了自身狀態導致Object.equals(Object)=true將導致一些問題。

2.2.2 LinkedHashSet

LinkedHashSet繼承自HashSet,其底層是基於LinkedHashMap來實現的,有序,非同步。LinkedHashSet集合同樣是根據元素的hashCode值來決定元素的存儲位置,但是它同時使用鏈表維護元素的次序。這樣使得元素看起來像是以插入順序保存的,也就是說,當遍歷該集合時候,LinkedHashSet將會以元素的添加順序訪問集合的元素。

2.2.3 TreeSet

TreeSet是一個有序集合,其底層是基於TreeMap實現的,非線程安全。TreeSet可以確保集合元素處於排序狀態。TreeSet支持兩種排序方式,自然排序和定制排序,其中自然排序為默認的排序方式。當我們構造TreeSet時,若使用不帶參數的構造函數,則TreeSet的使用自然比較器;若用戶需要使用自定義的比較器,則需要使用帶比較器的參數。
注意:TreeSet集合不是通過hashcode和equals函數來比較元素的.它是通過compare或者comparaeTo函數來判斷元素是否相等.compare函數通過判斷兩個對象的id,相同的id判斷為重復元素,不會被加入到集合中。

3 Map接口

Map與List、Set接口不同,它是由一系列鍵值對組成的集合,提供了key到Value的映射。同時它也沒有繼承Collection。在Map中它保證了key與value之間的一一對應關系。也就是說一個key對應一個value,所以它不能存在相同的key值,當然value值可以相同。

3.1 HashMap

以哈希表數據結構實現,查找對象時通過哈希函數計算其位置,它是為快速查詢而設計的,其內部定義了一個hash表數組(Entry[] table),元素會通過哈希轉換函數將元素的哈希地址轉換成數組中存放的索引,如果有沖突,則使用散列鏈表的形式將所有相同哈希地址的元素串起來,可能通過查看HashMap.Entry的源碼它是一個單鏈表結構。

3.2 LinkedHashMap

LinkedHashMap是HashMap的一個子類,它保留插入的順序,如果需要輸出的順序和輸入時的相同,那么就選用LinkedHashMap。
LinkedHashMap是Map接口的哈希表和鏈接列表實現,具有可預知的迭代順序。此實現提供所有可選的映射操作,並允許使用null值和null鍵。此類不保證映射的順序,特別是它不保證該順序恆久不變。
LinkedHashMap實現與HashMap的不同之處在於,后者維護着一個運行於所有條目的雙重鏈接列表。此鏈接列表定義了迭代順序,該迭代順序可以是插入順序或者是訪問順序。
根據鏈表中元素的順序可以分為:按插入順序的鏈表,和按訪問順序(調用get方法)的鏈表。默認是按插入順序排序,如果指定按訪問順序排序,那么調用get方法后,會將這次訪問的元素移至鏈表尾部,不斷訪問可以形成按訪問順序排序的鏈表。
注意,此實現不是同步的。如果多個線程同時訪問鏈接的哈希映射,而其中至少一個線程從結構上修改了該映射,則它必須保持外部同步。
由於LinkedHashMap需要維護元素的插入順序,因此性能略低於HashMap的性能,但在迭代訪問Map里的全部元素時將有很好的性能,因為它以鏈表來維護內部順序。

3.3 TreeMap

TreeMap 是一個有序的key-value集合,非同步,基於紅黑樹(Red-Black tree)實現,每一個key-value節點作為紅黑樹的一個節點。TreeMap存儲時會進行排序的,會根據key來對key-value鍵值對進行排序,其中排序方式也是分為兩種,一種是自然排序,一種是定制排序,具體取決於使用的構造方法。
自然排序:TreeMap中所有的key必須實現Comparable接口,並且所有的key都應該是同一個類的對象,否則會報ClassCastException異常。
定制排序:定義TreeMap時,創建一個comparator對象,該對象對所有的treeMap中所有的key值進行排序,采用定制排序的時候不需要TreeMap中所有的key必須實現Comparable接口。
TreeMap判斷兩個元素相等的標准:兩個key通過compareTo()方法返回0,則認為這兩個key相等。
如果使用自定義的類來作為TreeMap中的key值,且想讓TreeMap能夠良好的工作,則必須重寫自定義類中的equals()方法,TreeMap中判斷相等的標准是:兩個key通過equals()方法返回為true,並且通過compareTo()方法比較應該返回為0。
image

4 Iterator 與 ListIterator詳解

4.1 Iterator

Iterator的定義如下:

public interface Iterator<E> {}

Java的Iterator(迭代器)是一個設計模式,它使你可以遍歷一個容器(如列表,集合,隊列等)。它提供了一種方法來順序訪問聚合對象的元素,而不需要暴露該對象的內部表示。
Iterator提供的API接口如下:

  • boolean hasNext():判斷集合里是否存在下一個元素。如果有,hasNext()方法返回 true。
  • Object next():返回集合里下一個元素。
  • void remove():刪除集合里上一次next方法返回的元素。
    參考如下:
import java.util.*;  
  
public class Main {  
  public static void main(String[] args) {  
     // 創建一個ArrayList對象
        List<String> list = new ArrayList<>();
        list.add("Hello");
        list.add("World");
        list.add("Java");

        // 獲取該ArrayList的迭代器
        Iterator<String> it = list.iterator();

        // 使用迭代器遍歷列表中的元素
        while(it.hasNext()) {
            String element = it.next();
            System.out.println(element);
            if ("Java".equals(element)) {
                it.remove();
            }
        }
        // 移除之后的ArrayList對象
        System.out.println("after remove element 「java」: " + list);
  }  
}

輸出結果如下:

Hello
World
Java
remove java element : [Hello, World]

需要注意的點如下:

  • Iterator只能單向移動。
  • Iterator.remove()是唯一安全在迭代過程中修改集合;如果在迭代過程中以任何其它的方式修改了基本集合將會產生未知的行為。而且每調用一次next()方法,remove()方法只能被調用一次,如果違反這個規則將拋出一個異常,因為可能導致數據異常。

4.2 ListIterator

ListIterator是一個功能更加強大的迭代器, 它繼承於Iterator接口,只能用於各種List類型的訪問。它提供了在列表中插入和刪除元素的方法,以及使用hasPrevious()和previous()方法在迭代過程中向前和向后遍歷列表的功能。
以下是ListIterator的主要方法:

  • boolean hasNext(): 返回true如果迭代器有下一個元素。
  • Object next(): 返回迭代器的下一個元素並將指針移到下一個元素。
  • boolean hasPrevious(): 返回true如果迭代器有前一個元素。
  • Object previous(): 返回迭代器的前一個元素並將指針移到前一個元素。
  • int nextIndex(): 返回迭代器下一次要訪問的元素的索引。
  • int previousIndex(): 返回迭代器上一次訪問的元素的索引。
  • void remove(): 從列表中刪除迭代器最后一次返回的元素。
  • void add(Object o): 在迭代器指向的位置插入指定的元素。
  • void set(E e): 從列表中替換迭代器最后一次返回的元素。
public interface ListIterator<E> extends Iterator<E> {
    boolean hasNext(); 
    E next(); 
    boolean hasPrevious(); 
    E previous(); 
    int nextIndex(); 
    int previousIndex(); 
    void remove(); 
    void set(E e); 
    void add(E e);
}

由以上定義我們可以推出ListIterator可以:

  • 雙向移動(向前或者向后遍歷)
  • 產生相對於迭代器在列表中指向的當前位置的前一個和后一個元素的索引
  • 可以使用set()方法替換它訪問過的最后一個元素
  • 可以使用add()方法在next()方法返回的元素之前或previous()方法返回的元素之后插入一個元素

使用示例:

    public static void listIteratorWork() {
        // 創建一個 ArrayList
        List<String> list = new ArrayList<>();
        list.add("Element A");
        list.add("Element B");
        list.add("Element C");

        System.out.println("當前列表 : " + list);

        // 獲取 ListIterator 對象
        ListIterator<String> listIterator = list.listIterator();
        // 使用 hasNext() 和 next() 方法迭代列表
        System.out.println("逐一遍歷 : ");
        while (listIterator.hasNext()) {
            System.out.println(listIterator.next() + ", " + listIterator.previousIndex() + ", " + listIterator.nextIndex());
        }

        // 在迭代過程中使用 add() 方法添加元素
        listIterator.add("Element D");
        System.out.println("添加一個元素之后:" + list);


        // 在迭代過程中使用 set() 方法進行元素修改
        listIterator = list.listIterator(1);
        System.out.print("修改一個元素之后:");
        while (listIterator.hasNext()) {
            if ("Element D".equals(listIterator.next())) {
                listIterator.set("Element replace");
            }           
        }
        System.out.println(list);        
    }

輸出結果如下:

當前列表 : [Element A, Element B, Element C]
逐一遍歷 : 
Element A, 0, 1
Element B, 1, 2
Element C, 2, 3
添加一個元素之后:[Element A, Element B, Element C, Element D]
修改一個元素之后:[Element A, Element B, Element C, Element replace]

5 面試考點分析

5.1 ArrayList和LinkedList對比

  • ArrayList是實現了基於動態數組的數據結構,LinkedList基於鏈表的數據結構。
  • 兩者都是線程不安全,都實現了Collection接口。
  • 數據結構:ArrayList是基於動態數組的數據結構,LinkedList是基於雙向鏈表的數據結構。
  • 性能:ArrayList支持隨機訪問,查詢快,增刪慢,查詢的時間復雜度為O(1),插入和刪除的時間復雜度為O(n),因為對插入和刪除位置后面的元素進行移動位置,以保證內存的連續性,所以
    • 對於隨機訪問get和set,ArrayList絕對優於LinkedList,因為LinkedList要移動指針。
    • 對於新增和刪除操作add和remove,LinedList比較占優勢,因為ArrayList要移動數據。
  • 內存空間占用: ArrayList的空 間浪費主要體現在在list列表的結尾會預留一定的容量空間,而LinkedList的空間花費則體現在它的每一個元素都需要消耗 比ArrayList更多的空間(因為要存放直接后繼和直接前驅以及數據)。

5.2 HashTable與HashMap對比

  • 相同點:
    • 都實現了Map、Cloneable、java.io.Serializable接口。
    • 都是存儲"鍵值對(key-value)"的散列表,而且都是采用拉鏈法實現的。
  • 不同點:
    • 是否安全:HashMap是非線程安全的,HashTable 是線程安全的;HashTable 內部的方法基本都經過 synchronized 修飾。(如果你要保證線程安全的話就使用 ConcurrentHashMap )
    • 同步性:HashTable是線程安全的,也就是說是同步的,而HashMap是線程序不安全的,不是同步的 。
    • 對null值的處理:HashMap的key、value都可為null,HashTable的key、value都不可為null 。
    • 基類不同:HashMap繼承於AbstractMap,而Hashtable繼承於Dictionary。
    • 支持的遍歷種類不同:HashMap只支持Iterator(迭代器)遍歷。而Hashtable支持Iterator(迭代器)和Enumeration(枚舉器)兩種方式遍歷。
    • 操作效率:因為線程安全的問題,HashMap 要比 HashTable 效率高一點。另外,HashTable 基本被淘汰,不要在代碼中使用它;
    • 對Null key 和Null value的支持: HashMap 中,null 可以作為鍵,這樣的鍵只有一個,可以有一個或多個鍵所對應的值為 null。但是在 HashTable 中 put 進的鍵值只要有一個 null,直接拋出 NullPointerException
    • 初始容量大小和每次擴充容量大小的不同 :
      • 創建時如果不指定容量初始值,Hashtable 默認的初始大小為11,之后每次擴充,容量變為原來的2n+1。HashMap 默認的初始化大小為16。之后每次擴充,容量變為原來的2倍。
      • 創建時如果給定了容量初始值,那么 Hashtable 會直接使用你給定的大小,而 HashMap 會將其擴充為2的冪次方大小。也就是說 HashMap 總是使用2的冪作為哈希表的大小,后面會介紹到為什么是2的冪次方。
    • 底層數據結構: JDK1.8 以后的 HashMap 在解決哈希沖突時有了較大的變化,當鏈表長度大於閾值(默認為8)時,將鏈表轉化為紅黑樹,以減少搜索時間。Hashtable 沒有這樣的機制。

5.3 LinkedHashMap和TreeMap比較

LinkedHashMap保存了記錄的插入順序,在用Iterator遍歷LinkedHashMap時,先得到的記錄肯定是先插入的,也可以在構造時用帶參數,按照應用次數排序。在遍歷的時候會比HashMap慢。

TreeMap實現SortMap接口,內部實現是紅黑樹。能夠把它保存的記錄根據鍵排序,默認是按鍵值的升序排序,也可以指定排序的比較器,當用Iterator 遍歷TreeMap時,得到的記錄是排過序的。TreeMap不允許key的值為null。非同步的。

5.4 HashSet、LinkedHashSet、TreeSet比較

5.4.1 Set接口

Set不允許包含相同的元素,如果試圖把兩個相同元素加入同一個集合中,add方法返回false。
Set判斷兩個對象相同不是使用==運算符,而是根據equals方法。也就是說,只要兩個對象用equals方法比較返回true,Set就不會接受這兩個對象。

5.4.2 HashSet

HashSet有以下特點:

  • 不能保證元素的排列順序,順序有可能發生變化。
  • 不是同步的。
  • 集合元素可以是null,但只能放入一個null。
    HashSet集合判斷兩個元素相等的標准是兩個對象通過equals方法比較相等,並且兩個對象的hashCode()方法返回值也相等。

5.4.3 LinkedHashSet

LinkedHashSet集合同樣是根據元素的hashCode值來決定元素的存儲位置,但是它同時使用鏈表維護元素的次序。這樣使得元素看起來像是以插入順序保存的,也就是說,當遍歷該集合時候,LinkedHashSet將會以元素的添加順序訪問集合的元素。
LinkedHashSet在迭代訪問Set中的全部元素時,性能比HashSet好,但是插入時性能稍微遜色於HashSet。

5.4.4 TreeSet類

TreeSet是SortedSet接口的唯一實現類,TreeSet可以確保集合元素處於排序狀態。TreeSet支持兩種排序方式,自然排序和定制排序,其中自然排序為默認的排序方式。向TreeSet中加入的應該是同一個類的對象。
TreeSet判斷兩個對象不相等的方式是兩個對象通過equals方法返回false,或者通過CompareTo方法比較沒有返回0。

5.5 Iterator和ListIterator區別

  • ListIterator有add()方法,可以向List中添加對象,而Iterator不能
  • ListIterator和Iterator都有hasNext()和next()方法,可以實現順序向后遍歷,但是ListIterator有hasPrevious()和previous()方法,可以實現逆向(順序向前)遍歷。Iterator就不可以。
  • ListIterator可以定位當前的索引位置,nextIndex()和previousIndex()可以實現。Iterator沒有此功能。
  • 都可實現刪除對象,但是ListIterator可以實現對象的修改,set()方法可以實現。Iierator僅能遍歷,不能修改。
    因為ListIterator的這些功能,可以方便的實現對LinkedList等List數據結構的操作。其實,數組對象也可以用迭代器來實現。

5.6 Collection 和 Collections區別

Java中的Collection和Collections都是用於處理集合的類,但它們有一些重要的區別。

繼承關系:Collection是所有集合類的根接口,它定義了集合的基本操作,比如添加元素、刪除元素等。Collections是一個幫助類,它提供了靜態方法來操作和操作集合,比如排序、查找等。Collections類通過實現和實例化集合類的各種基本操作,讓集合類的操作更加簡單。
用法:Collection通常用於定義集合類的基本操作,而Collections則提供了各種靜態方法來操作和操作集合。Collections類中包含了很多有用的靜態方法,比如排序、查找、復制等。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2024 CODEPRJ.COM