在 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,特點是元素有序、可重複,且允許通過索引操作元素。常用實現類有ArrayList、LinkedList、Vector。
(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.synchronizedList或CopyOnWriteArrayList)。
3. Set 接口:無序不可重複的元素集合
Set接口繼承自Collection,特點是元素無序、不可重複(基於元素的equals()和hashCode()方法判斷唯一性)。常用實現類有HashSet、LinkedHashSet、TreeSet。
(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)可重複。常用實現類有HashMap、TreeMap、Hashtable、LinkedHashMap。
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 緩存(基於訪問順序)。
四、集合體系的選擇策略
在實際開發中,如何選擇合適的集合?可以參考以下策略:
|
需求場景
|
推薦集合
|
|
有序可重複,隨機訪問
|
|
|
有序可重複,頻繁增刪
|
|
|
無序不可重複,效率優先
|
|
|
無序不可重複,需插入順序
|
|
|
無序不可重複,需排序
|
|
|
鍵值對映射,效率優先
|
|
|
鍵值對映射,需鍵排序
|
|
|
鍵值對映射,需插入順序
|
|
五、總結
Java 集合體系是 Java 編程的核心基石之一,掌握Collection和Map的各類實現類的特性、用法和適用場景,能讓你在數據處理場景中如魚得水。從ArrayList的數組高效查詢,到LinkedList的鏈表靈活增刪;從HashMap的哈希表極速映射,到TreeMap的紅黑樹有序排列,每一種集合都有其獨特價值。