Java 集合用於存儲對象,長度可變,支援異構元素。核心接口三大支柱:
List(有序、可重復)、Set(無序、唯一)學習策略:抓數據結構 → 推導特性 → 記核心 API → 看源碼關鍵點。
| 實現類 | 底層結構 | 特點 | 適用場景 |
|---|---|---|---|
| ArrayList | 動態數組 | 隨機訪問 O(1),尾部增刪 O(1),中間增刪 O(n),非線程安全 | 查多改少、需下標訪問 |
| LinkedList | 雙向鏈表 | 首尾增刪 O(1),順序遍歷快,隨機訪問 O(n),實現 Deque | 改多查少、棧/隊列、頻繁首尾操作 |
| Vector | 動態數組 | 線程安全(synchronized),性能差,已被 Collections.synchronizedList / CopyOnWriteArrayList 替代 | 極少用 |
private void grow(int minCapacity) {
int oldCapacity = elementData.length;
int newCapacity = oldCapacity + (oldCapacity >> 1); // 1.5 倍
elementData = Arrays.copyOf(elementData, newCapacity);
}
默認初始容量 10,首次 add 若為空數組則擴至 10。
private static class Node<E> {
E item;
Node<E> next;
Node<E> prev;
}
雙向鏈表,頭尾指針 first/last,索引查找採用「二分方向」優化:index < size/2 從頭找,否則從尾找。
| 實現類 | 底層 | 有序性 | 唯一性判斷 | 線程安全 |
|---|---|---|---|---|
| HashSet | HashMap | 無序 | hashCode() + equals() | 否 |
| LinkedHashSet | LinkedHashMap | 插入序 | hashCode() + equals() | 否 |
| TreeSet | TreeMap (紅黑樹) | 自然序/定製序 | Comparable / Comparator | 否 |
本質:HashSet 內部持有 HashMap<E, Object>,Value 統一用 PRESENT 佔位對象。
Node<K,V>[] table、size、threshold = capacity * loadFactor(默認 0.75)、modCount。size++ → 達閾值 resize()(擴容 2 倍)。key.equals() → 命中返回 value。put 導致鏈表成環、數據丟失。並發場景用 ConcurrentHashMap。O(log n) 增刪查。Comparable 或構造傳入 Comparator。firstKey()、lastKey()、lowerKey()、higherKey()、subMap() 等極其實用。// HashMap 推薦:entrySet 避免二次 get
for (Map.Entry<K,V> e : map.entrySet()) { ... }
// ArrayList 推薦:for 索引 / for-each > Iterator
// LinkedList 推薦:for-each / Iterator(避免 get(index) O(n))
| 維度 | Comparable | Comparator |
|---|---|---|
| 位置 | 元素類內部(內部比較) | 外部獨立類(策略模式) |
| 方法 | compareTo(T o) | compare(T o1, T o2) |
| 修改元素類 | 需修改 | 無需修改 |
| 多種排序 | 僅一種自然序 | 可定義無限種策略 |
| 典型場景 | 自然順序(數字、字符串、日期) | 按姓名/年齡/分數等多維度排序 |
最佳實踐:元素類實現 Comparable 定義自然序;需多維排序時編寫獨立 Comparator 實現類或 Lambda。
sort(List) / sort(List, Comparator)shuffle(List) 洗牌reverse(List) 反轉binarySearch(List, key) 前提已排序max/min(Collection, Comparator)synchronizedXxx() 線程安全包裝unmodifiableXxx() 唯讀視圖sort(T[]) / sort(T[], Comparator)asList(T...) 數組 → List(定長,不可增刪)toString(array)、deepToString()stream(array) 並行流入口| 坑點 | 後果 | 規避 |
|---|---|---|
| ArrayList 作為方法參數被修改 | 調用方數據變動 | 傳入 new ArrayList<>(list) 或 Collections.unmodifiableList() |
| HashMap Key 為可變對象且修改了 hash 相關字段 | 無法獲取、內存洩漏 | Key 必須不可變(String、包裝類、自定義不可變類) |
遍歷中直接 list.remove() | ConcurrentModificationException | 用 Iterator.remove() 或收集待刪 ID 二次刪除 |
| Arrays.asList 基本類型數組 | 產生 List<int[]> 而非 List<Integer> | 用 Integer[] 或 IntStream.of(arr).boxed().collect(toList()) |
| TreeMap/Set 存儲未實現 Comparable 且無 Comparator 的對象 | 運行時 ClassCastException | 確保 Key 實現 Comparable 或構造傳 Comparator |
掌握集合框架的關鍵在於數據結構決定性能特徵。面試與實戰中,重點關注:
equals/hashCode vs Comparable/Comparator)Comparable(內部自然序)與 Comparator(外部策略)的配合使用Collections/Arrays 的高頻方法內化這些核心知識,集合相關問題將不再是難點。