Java 集合框架(JCF)是 java.util 套件的核心,提供統一的資料結構操作 API。頂層由兩大根介面劃分:
所有集合類僅儲存物件引用,不存物件本身;泛型僅在編譯期生效(類型擦除);容量動態擴展;提供豐富演算法(排序、搜尋、交集/聯集/差集)。
Object[] elementData,預設容量 10,擴容 1.5 倍get(index) O(1),記憶體連續,CPU 緩存友好,遍歷極快add(0, e) 效能極差Node<E>,含 prev/next/item,實作 DequeDeque 可作棧/佇列// 頭部插入 10 萬次 LinkedList: 23 ms // 指標操作 ArrayList: 1227 ms // 大量陣列複製 // 隨機存取 10 萬次 ArrayList: 6 ms // 直接索引 LinkedList: 5277 ms // 鏈表遍歷
結論:預設用 ArrayList,只有明確需要首尾高頻操作或 Deque 特性時才用 LinkedList。Vector 同步化開銷大,Stack 繼承 Vector 且 API 設計不佳,均不推薦,佇列請用 ArrayDeque。
核心機制:hashCode() 定位桶位 → equals() 精確比對。契約:equals 相等 → hashCode 必相等;hashCode 相等 → equals 不一定相等(哈希碰撞)。
| 實現 | 底層 | 順序 | Null 支援 | 適用場景 |
|---|---|---|---|---|
| HashSet | HashMap | 無序 | 允許 1 個 null | 高效去重、成員資格測試 |
| LinkedHashSet | LinkedHashMap | 插入順序 | 允許 1 個 null | 需保持插入順序的去重 |
| TreeSet | TreeMap (紅黑樹) | 自然順序/Comparator | 不允許 null | 需排序、範圍查詢 |
public class Person {
private String name; private int age;
// getter/setter...
@Override public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return Objects.equals(name, person.name); // 僅按姓名判斷相等
}
@Override public int hashCode() {
return Objects.hash(name); // 僅基於姓名計算 hash
}
}
// 測試
Set<Person> set = new HashSet<>();
set.add(new Person("lxp", 10));
set.add(new Person("lxp", 10)); // 重複,不會加入
set.add(new Person("lxp", 20)); // hashCode 不同,直接加入
// 結果:size=2
Comparable 或提供 Comparator,支援優先級處理(如任務調度)| 實現 | 底層 | 順序 | Null Key/Value | 執行緒安全 | 核心特性 |
|---|---|---|---|---|---|
| HashMap | 陣列+鏈表/紅黑樹 (JDK8) | 無序 | 允許 1 null key、多 null value | 非安全 | 通用高效映射,JDK8 鏈表轉樹優化碰撞 |
| LinkedHashMap | HashMap + 雙向鏈表 | 插入順序/存取順序 | 允許 | 非安全 | 保持順序、實作 LRU 快取 |
| TreeMap | 紅黑樹 | 鍵自然順序/Comparator | 不允許 null key | 非安全 | 有序映射、範圍查詢 |
| ConcurrentHashMap | CAS + synchronized + 節點鎖 (JDK8) | 無序 | 不允許 null | 高併發安全 | 分段鎖→節點鎖,讀無鎖,寫細粒度鎖 |
Hashtable 全表鎖(synchronized 鎖住整個 map),效能極差,**已棄用**。高併發場景請直接使用 ConcurrentHashMap,或配合 Collections.synchronizedMap() 包裝(但鎖粒度粗)。
Collection 繼承 Iterable,提供 iterator() 返回 Iterator<E>:
public interface Iterator<E> {
boolean hasNext();
E next();
void remove(); // 可選操作,支援邊遍歷邊刪除
}
for-each 語法糖編譯後即使用 Iterator,**禁止在 for-each 中直接修改集合結構**(會拋 ConcurrentModificationException),需使用 Iterator.remove() 或並發集合。
Collections.sort()、shuffle()、reverse()、binarySearch()、synchronizedList()、unmodifiableList()Arrays.sort()、asList()、stream()、parallelSort()排序相關緊密依賴 Comparable(自然順序)與 Comparator(定製順序),建議使用 Java 8 Comparator.comparing() 鏈式構建。
Java 集合框架以清晰的介面體系、豐富的實現類、統一的演算法支援,解決了 90% 以上的資料結構需求。理解底層資料結構(動態陣列、鏈表、紅黑樹、哈希表、堆)、掌握核心實現的時空複雜度與適用邊界、熟悉 hashCode/equals 契約與並發集合原理,是資深 Java 開發者的必修課。建議深入閱讀 JDK 原始碼(ArrayList、HashMap、ConcurrentHashMap、ArrayDeque),並在實際專案中根據效能剖析結果調整選型。