Java 集合框架是 Java 開發中最核心、使用頻率最高的 API 之一。本文基於 java.util 包,系統梳理 Collection、List、Set、Map 四大核心體系的繼承關係、核心特性、常用實現類及最佳實踐,並附帶實戰代碼示例,幫助開發者建立完整的集合知識體系。
Java 集合主要集中在兩個包中:
java.util:基礎集合框架java.util.concurrent:並發集合,在前者基礎上實現線程安全java.util 下的集合對象大致分為三大類:
List 接口Set 接口Map 接口其中 List 和 Set 繼承自 Collection 接口,Map 獨立繼承體系。
作為 List 和 Set 的父接口,Collection 定義了通用的集合操作:
| 分類 | 方法 | 說明 |
|---|---|---|
| 添加 | add(E e) / addAll(Collection<? extends E> c) | 添加單個/批量元素 |
| 刪除 | remove(Object o) / removeAll(Collection<?> c) / clear() | 刪除指定/批量/所有元素 |
| 查詢 | contains(Object o) / containsAll(Collection<?> c) / isEmpty() / size() | 包含判斷、空判斷、大小統計 |
| 轉換 | toArray() / toArray(T[] a) | 集合轉數組 |
| 遍歷 | iterator() | 獲取迭代器 |
// 方式一:迭代器遍歷(通用,支持刪除操作)
Iterator<Integer> iterator = collection.iterator();
while (iterator.hasNext()) {
System.out.println(iterator.next());
// iterator.remove(); // 安全刪除
}
// 方式二:增強 for 循環(語法簡潔,僅讀遍歷)
for (Integer value : collection) {
System.out.println(value);
}
List 是數組的動態擴展,特點:
null 值| 實現類 | 底層結構 | 線程安全 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|---|---|
| ArrayList | 動態數組 | 否 | 隨機訪問快 O(1)、內存效率高 | 插入刪除慢 O(n)、擴容有開銷 | 讀多寫少、頻繁隨機訪問 |
| LinkedList | 雙向鏈表 | 否 | 首尾增刪快 O(1)、實現 Deque | 隨機訪問慢 O(n)、內存開銷大 | 頻繁增刪、棧/隊列場景 |
| Vector | 動態數組 | 是(synchronized) | 線程安全 | 性能差、擴容策略固定 2倍 | 避免使用,推薦 Collections.synchronizedList 或 CopyOnWriteArrayList |
Vector<Integer> vector = new Vector<>();
for (int i = 0; i < 5; i++) vector.add(100);
vector.add(null); // 允許 null 和重複
System.out.println(vector); // [100, 100, 100, 100, 100, null]
// Vector 特有方法
System.out.println(vector.firstElement()); // 首元素
System.out.println(vector.lastElement()); // 尾元素
System.out.println(vector.subList(3, 8)); // 子列表視圖
LinkedList<Integer> list = new LinkedList<>();
// ... 添加元素 ...
System.out.println(list.peek()); // 查看隊首不移除
System.out.println(list.poll()); // 取出並移除隊首
System.out.println(list.pop()); // 棧彈出(同 pollFirst)
list.push(100); // 棧壓入(同 addFirst)
Set 存儲唯一元素,無序(除 LinkedHashSet/TreeSet),核心實現:
| 實現類 | 底層結構 | 有序性 | 線程安全 | 允許 null | 特點 |
|---|---|---|---|---|---|
| HashSet | HashMap | 無序 | 否 | 是(1個) | 性能最好,依賴 hashCode/equals |
| LinkedHashSet | LinkedHashMap | 插入序 | 否 | 是(1個) | 維護插入順序,迭代性能略低 |
| TreeSet | 紅黑樹 | 自然序/定製序 | 否 | 否 | 有序、範圍查詢、O(log n) 操作 |
HashSet 判斷元素相等依賴 hashCode() 和 equals() 契約:
// 自定義類型破壞 equals 契約示例
class MyInteger {
private Integer value;
// 固定 hashCode 導致所有對象進同一桶
public int hashCode() { return 1; }
// 永遠返回 true 導致所有對象視為相等
public boolean equals(Object obj) { return true; }
}
Set<MyInteger> set = new HashSet<>();
set.add(new MyInteger(100));
set.add(new MyInteger(100));
set.add(new MyInteger(100));
System.out.println(set.size()); // 輸出 1(視為同一元素)
// 正確實現應保證:
// 1. equals 相等 ⇒ hashCode 必相等
// 2. hashCode 相等 ⇏ equals 必相等(哈希碰撞)
// 實現 Comparable 定製降序
class MyInteger2 implements Comparable<MyInteger2> {
public int value;
public int compareTo(MyInteger2 o) {
return o.value - this.value; // 降序:大的排前面
}
}
TreeSet<MyInteger2> set = new TreeSet<>();
set.add(new MyInteger2(10));
set.add(new MyInteger2(5));
set.add(new MyInteger2(20));
System.out.println(set); // [20, 10, 5] 降序
Map 存儲鍵值對,Key 唯一,Value 可重複。核心實現對比:
| 實現類 | 底層結構 | 有序性 | 線程安全 | 允許 null Key | 允許 null Value | 特點 |
|---|---|---|---|---|---|---|
| HashMap | 數組+鏈表/紅黑樹 | 無序 | 否 | 是(1個) | 是 | JDK1.8+ 鏈表轉紅黑樹優化 |
| Hashtable | 數組+鏈表 | 無序 | 是 | 否 | 否 | 舊類,性能差,不推薦 |
| LinkedHashMap | HashMap+雙向鏈表 | 插入序/訪問序 | 否 | 是(1個) | 是 | 可實現 LRU 緩存 |
| TreeMap | 紅黑樹 | Key 自然序/定製序 | 否 | 否 | 是 | 有序 Map、範圍查詢 |
預估數據量大時,建議指定初始容量避免頻繁擴容:new HashMap<>(expectedSize * 4 / 3 + 1)
Map<Integer, String> hashMap = new HashMap<>();
hashMap.put(null, null); // 允許
hashMap.put(1, null); // 允許
Map<Integer, String> hashtable = new Hashtable<>();
hashtable.put(null, null); // 拋出 NullPointerException
hashtable.put(1, null); // 拋出 NullPointerException
List<String> list = new ArrayList<>(); 便於後續替換實現ClassCastExceptionCopyOnWriteArrayList / CopyOnWriteArraySetConcurrentHashMap / ConcurrentSkipListMap / ConcurrentLinkedQueue掌握 Java 集合框架的核心在於理解底層數據結構特性與業務場景的匹配。沒有「最好」的集合,只有「最合適」的集合。