集合體系概覽
| 介面 | 語義 | 典型實現 | 核心特點 |
List | 有序、可重複 | ArrayList、LinkedList | 線性序列,支援索引隨機存取 |
Set | 無序、不可重複 | HashSet、TreeSet、LinkedHashSet | 去重、集合運算 |
Map | 鍵值映射、Key 唯一 | HashMap、TreeMap、LinkedHashMap、Hashtable | 鍵值對存取、索引查找 |
List 實現深度剖析
ArrayList:動態陣列
- 底層
Object[] elementData,預設容量 10
- 擴容機制:
newCapacity = oldCapacity + (oldCapacity >> 1) (1.5 倍)
- 擴容觸發
Arrays.copyOf 複制陣列,**大量資料頻繁擴容會導致效能抖動**
- 隨機存取 O(1),尾部新增 O(1) 攤銷,中間插入/刪除 O(n)
- 建議:預估資料量時指定
new ArrayList<>(initialCapacity)
LinkedList:雙向鏈表
- 節點結構:
Node<E> { E item; Node<E> next, prev; }
- 頭尾指標
first、last,新增/刪除僅調整指標 O(1)
- 隨機存取 O(n),不支援高效索引操作
- 實作
Deque,可作棧/佇列使用
- 記憶體開銷大(每節點額外 2 個引用)
Map 實現深度剖析
HashMap (JDK 8+):陣列 + 鏈表/紅黑樹
- 預設負載因子 0.75,閾值 8 轉紅黑樹,6 退化鏈表
hash(key) 計算索引,解決碰撞
- **非線程安全**,多執行緒用
ConcurrentHashMap
- Key 為 null 允許,存放於索引 0
Hashtable:同步版 HashMap
- 所有 public 方法
synchronized,效能較差
- 不允許 null Key/Value
- 已被
ConcurrentHashMap 取代
TreeMap:紅黑樹實現 NavigableMap
- Key **天然有序**(自然序或 Comparator)
- PUT/GET/REMOVE 皆 O(log n)
- 支援
firstKey()、subMap()、floorKey() 等範圍操作
- 插入/刪除需維護樹平衡(旋轉、重新著色),比 HashMap 複雜
Set 實現深度剖析
HashSet:基於 HashMap 實現
private transient HashMap<E, Object> map;
public boolean add(E e) { return map.put(e, PRESENT) == null; }
- 元素作為 Key 存入內部 HashMap,Value 固定
PRESENT
- 利用 Key 唯一性實現去重,存取 O(1)
- 無序、非線程安全
TreeSet:基於 TreeMap 實現
public TreeSet() { this(new TreeMap<E, Object>()); }
public boolean add(E e) { return m.put(e, PRESENT) == null; }
- 元素按自然序或 Comparator 排序
- 支援
first()、last()、subSet() 等有序操作
- 操作複雜度 O(log n)
LinkedHashSet:維護插入順序
- 基於 LinkedHashMap,雙向鏈表記錄插入序
- 迭代順序 = 插入順序
選型決策樹
需要鍵值對? → Map
├─ 高併發 → ConcurrentHashMap
├─ 需排序/範圍查詢 → TreeMap
├─ 需插入順序 → LinkedHashMap
└─ 一般場景 → HashMap
不需要鍵值,需去重? → Set
├─ 需排序 → TreeSet
├─ 需插入順序 → LinkedHashSet
└─ 一般場景 → HashSet
需要有序列表、可重複? → List
├─ 頻繁隨機存取、尾部新增 → ArrayList
├─ 頻繁頭尾增刪、作佇列/棧 → LinkedList
└─ 唯讀/少量資料 → Arrays.asList / List.of (Java 9+)
效能對照表 (百萬級資料參考)
| 操作 | ArrayList | LinkedList | HashMap | TreeMap | HashSet | TreeSet |
| 隨機存取 | ★★★★★ | ★☆☆☆☆ | ★★★★★ | ★★★★☆ | ★★★★★ | ★★★★☆ |
| 尾部新增 | ★★★★★ | ★★★★★ | - | - | ★★★★★ | ★★★★☆ |
| 中間插入 | ★★☆☆☆ | ★★★☆☆ | - | - | - | - |
| 查找/Contains | ★★☆☆☆ | ★★☆☆☆ | ★★★★★ | ★★★★☆ | ★★★★★ | ★★★★☆ |
| 記憶體效率 | ★★★★★ | ★★☆☆☆ | ★★★★☆ | ★★★☆☆ | ★★★★☆ | ★★★☆☆ |
常見坑點提醒
- ArrayList 擴容拷貝:大量資料預設初始容量
- HashMap 多執行緒死循環:JDK 7 擴容頭插法導致環形鏈表,JDK 8 改尾插但仍非線程安全
- TreeMap Key 必須實作 Comparable 或提供 Comparator:否則拋
ClassCastException
- Set 存放可變物件:修改物件導致 hashCode 改變,無法正確查找/刪除
Collections.unmodifiableList 等僅提供**視圖保護**,底層集合仍可被修改