在 Java 編程世界中,集合框架是處理數據集合的核心工具,它為我們提供了一系列高效、靈活的數據結構,幫助我們應對各種複雜的存儲與操作需求。本文將帶你係統性地學習 Java 集合體系,從接口到實現類,從基礎用法到進階技巧,讓你徹底掌握這一核心知識點。

一、集合體系總覽

Java 集合框架主要分為兩大體系:Collection 體系Map 體系

  • Collection 體系:以Collection接口為根,強調 “單個元素” 的集合操作,包含List(有序可重複)、Set(無序不可重複)、Queue(隊列,先進先出)三大分支。
  • Map 體系:以Map接口為根,強調 “鍵值對(Key-Value)” 的映射關係,用於存儲具有映射邏輯的數據。

二、Collection 集合體系深度解析

1. Collection 接口:集合的通用契約

  Collection是所有單列集合的根接口,定義了集合的通用方法,如:

  • boolean add(E e):添加元素
  • boolean remove(Object o):移除元素
  • boolean contains(Object o):判斷是否包含元素
  • int size():獲取元素個數
  • Iterator<E> iterator():獲取迭代器,用於遍歷集合

       這些方法是操作集合的基礎,所有Collection的實現類都必須遵守這些契約。

2. List 接口:有序可重複的元素序列

List接口繼承自Collection,特點是元素有序、可重複,且允許通過索引操作元素。常用實現類有ArrayListLinkedListVector

(1)ArrayList
  • 底層實現:動態數組(數組擴容機制)。
  • 核心特點:查詢快(基於索引的隨機訪問)、增刪慢(數組元素移動成本高)。
  • 適用場景:讀多寫少的業務場景,如數據查詢、列表展示。

示例代碼

List arrayList = new ArrayList<>();
arrayList.add("Java");
arrayList.add("Python");
arrayList.add("Java"); // 允許重複
System.out.println(arrayList.get(0)); // 輸出"Java"
(2)LinkedList
  • 底層實現:雙向鏈表。
  • 核心特點:查詢慢(需遍歷鏈表)、增刪快(只需修改節點引用)。
  • 適用場景:寫多讀少的業務場景,如頻繁插入、刪除元素的隊列、棧結構。

示例代碼

List linkedList = new LinkedList<>();
linkedList.add("Spring");
linkedList.add("Spring Boot");
linkedList.remove(0); // 移除第一個元素
(3)Vector
  • 底層實現:動態數組(線程安全版 ArrayList)。
  • 核心特點:線程安全(方法加同步鎖)、效率低。
  • 適用場景:多線程環境下的集合操作(但現在更推薦Collections.synchronizedListCopyOnWriteArrayList)。

3. Set 接口:無序不可重複的元素集合

Set接口繼承自Collection,特點是元素無序、不可重複(基於元素的equals()hashCode()方法判斷唯一性)。常用實現類有HashSetLinkedHashSetTreeSet

(1)HashSet
  • 底層實現:哈希表(基於HashMap,元素作為 Map 的 Key,Value 為固定對象)。
  • 核心特點:無序、去重、查詢效率高。
  • 注意點:元素需正確重寫equals()hashCode()方法,否則去重邏輯會失效。

示例代碼

Set hashSet = new HashSet<>();
hashSet.add("Apple");
hashSet.add("Banana");
hashSet.add("Apple"); // 重複元素會被過濾
System.out.println(hashSet.size()); // 輸出2
(2)LinkedHashSet
  • 底層實現:哈希表 + 鏈表(基於LinkedHashMap)。
  • 核心特點:有序(插入順序)、去重、查詢效率高。
  • 適用場景:需要保留插入順序的去重場景。
(3)TreeSet
  • 底層實現:紅黑樹(基於TreeMap)。
  • 核心特點:有序(自然排序或自定義比較器排序)、去重。
  • 適用場景:需要對元素排序的去重場景。

示例代碼

Set treeSet = new TreeSet<>();
treeSet.add(3);
treeSet.add(1);
treeSet.add(2);
System.out.println(treeSet); // 輸出[1, 2, 3],自動排序

4. Queue 隊列接口:先進先出的數據結構

  Queue是一種 “先進先出(FIFO)” 的集合,常用於任務排隊、消息隊列等場景。常用實現類有LinkedList(同時實現 List 和 Queue)、PriorityQueue(優先隊列)。

示例代碼(隊列的入隊、出隊)

Queue queue = new LinkedList<>();
queue.offer("Task1"); // 入隊
queue.offer("Task2");
queue.offer("Task3");
System.out.println(queue.poll()); // 出隊,輸出"Task1"

5. 集合的遍歷方式

       遍歷集合是日常開發的高頻操作,Java 提供了多種遍歷方式:

  • 普通 for 循環:僅適用於List(通過索引訪問)。
for (int i = 0; i < list.size(); i++) {
    System.out.println(list.get(i));
}
  • 增強 for 循環(foreach):適用於所有Collection集合,語法簡潔。
for (String elem : set) {
    System.out.println(elem);
}
  • 迭代器遍歷:分為普通迭代器Iterator和雙向迭代器ListIterator(僅List支持)。
Iterator iterator = collection.iterator();
while (iterator.hasNext()) {
    String elem = iterator.next();
    System.out.println(elem);
    // 支持遍歷中刪除元素(避免併發修改異常)
    iterator.remove();
}

6. 集合中的泛型 <E>

       泛型是 Java 的 “類型安全” 機制,用於限制集合中元素的類型,避免運行時類型轉換異常。

示例代碼

// 泛型指定元素為String,編譯期就會檢查類型
List genericList = new ArrayList<>();
genericList.add("Hello");
// genericList.add(123); // 編譯報錯,不允許添加非String類型

7. 可變參數

       可變參數允許方法接收任意數量的同類型參數,語法為類型... 參數名,在集合操作中常用於批量添加元素。

示例代碼

public static void addAll(List list, String... elems) {
    for (String elem : elems) {
        list.add(elem);
    }
}
// 調用
List list = new ArrayList<>();
addAll(list, "a", "b", "c");

8. 數組工具類(Arrays)

java.util.Arrays提供了數組操作的工具方法,如數組轉集合、數組排序、二分查找等。

示例代碼

String[] arr = {"a", "b", "c"};
// 數組轉List(注意:返回的是不可變List,不能增刪元素)
List arrList = Arrays.asList(arr);
// 數組排序
int[] intArr = {3, 1, 2};
Arrays.sort(intArr);

9. 集合工具類(Collections)

java.util.Collections提供了集合操作的工具方法,如排序、查找、線程安全包裝等。

示例代碼

List list = new ArrayList<>();
list.add(3);
list.add(1);
list.add(2);
// 排序
Collections.sort(list);
System.out.println(list); // 輸出[1, 2, 3]
// 線程安全包裝
List syncList = Collections.synchronizedList(new ArrayList<>());

三、Map 集合體系深度解析

Map是 “鍵值對” 映射的集合,鍵(Key)唯一,值(Value)可重複。常用實現類有HashMapTreeMapHashtableLinkedHashMap

1. Map 接口的核心方法

  • V put(K key, V value):添加鍵值對
  • V get(Object key):根據鍵獲取值
  • boolean containsKey(Object key):判斷是否包含鍵
  • boolean containsValue(Object value):判斷是否包含值
  • Set<K> keySet():獲取所有鍵的集合
  • Collection<V> values():獲取所有值的集合
  • Set<Map.Entry<K, V>> entrySet():獲取所有鍵值對的集合

2. HashMap

  • 底層實現:哈希表(數組 + 鏈表 + 紅黑樹,JDK8 及以後)。
  • 核心特點:無序、鍵唯一、效率高(查詢、增刪均為 O (1) 級別)。
  • 注意點:默認初始容量 16,負載因子 0.75,擴容時容量翻倍;鍵為null時會被存到索引 0 的位置。

示例代碼

Map hashMap = new HashMap<>();
hashMap.put("Java", 100);
hashMap.put("Python", 90);
hashMap.put("Java", 95); // 鍵重複,值會覆蓋
System.out.println(hashMap.get("Java")); // 輸出95,>

3. TreeMap

  • 底層實現:紅黑樹。
  • 核心特點:有序(鍵的自然排序或自定義比較器排序)、鍵唯一。
  • 適用場景:需要對鍵排序的映射場景。

示例代碼

Map treeMap = new TreeMap<>();
treeMap.put(3, "C");
treeMap.put(1, "A");
treeMap.put(2, "B");
System.out.println(treeMap); // 輸出{1=A, 2=B, 3=C},按鍵排序,>

4. Hashtable

  • 底層實現:哈希表(線程安全版 HashMap)。
  • 核心特點:線程安全(方法加同步鎖)、效率低、鍵和值都不允許為null
  • 適用場景:古老的多線程場景(現在更推薦ConcurrentHashMap)。

5. LinkedHashMap

  • 底層實現:哈希表 + 鏈表。
  • 核心特點:有序(插入順序或訪問順序)、鍵唯一、效率高。
  • 適用場景:需要保留插入 / 訪問順序的映射場景,如 LRU 緩存(基於訪問順序)。

四、集合體系的選擇策略

在實際開發中,如何選擇合適的集合?可以參考以下策略:

需求場景

推薦集合

有序可重複,隨機訪問

ArrayList

有序可重複,頻繁增刪

LinkedList

無序不可重複,效率優先

HashSet

無序不可重複,需插入順序

LinkedHashSet

無序不可重複,需排序

TreeSet

鍵值對映射,效率優先

HashMap

鍵值對映射,需鍵排序

TreeMap

鍵值對映射,需插入順序

LinkedHashMap

五、總結

       Java 集合體系是 Java 編程的核心基石之一,掌握CollectionMap的各類實現類的特性、用法和適用場景,能讓你在數據處理場景中如魚得水。從ArrayList的數組高效查詢,到LinkedList的鏈表靈活增刪;從HashMap的哈希表極速映射,到TreeMap的紅黑樹有序排列,每一種集合都有其獨特價值。