首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 集合框架全景圖:List/Set/Map 核心實現原理、選型指南與並發避坑

     編輯:Java 相關知識

集合體系繼承圖譜

Collection
 ├─ List (有序、可重複)
 │   ├─ ArrayList  (動態數組、隨機訪問快)
 │   ├─ LinkedList (雙向鏈表、首尾增刪快)
 │   ├─ Vector     (同步舊類、不推薦新代碼用)
 │   └─ Stack      (Vector 子類、LIFO)
 └─ Set (無序、不可重複)
     ├─ HashSet    (HashMap 底層、O(1) 查找)
     ├─ LinkedHashSet (維護插入序)
     └─ TreeSet    (紅黑樹、有序、O(log n))

Map (鍵值對、Key 唯一)
 ├─ HashMap      (數組+鏈表/紅黑樹、非同步)
 ├─ Hashtable    (同步舊類、Key/Value 不可為 null)
 ├─ LinkedHashMap (維護插入/訪問序)
 ├─ TreeMap      (紅黑樹、Key 有序)
 └─ WeakHashMap  (Key 弱引用、適合緩存)

核心實現原理速覽

集合底層結構線程安全Null 支持順序性典型場景
ArrayList動態數組否是插入序隨機訪問、遍歷多、增刪少
LinkedList雙向鏈表否是插入序首尾增刪多、實現 Queue/Deque
HashMap數組+鏈表/紅黑樹否Key/Value 均可 null無序高性能 KV 存取
Hashtable數組+鏈表是 (synchronized)Key/Value 不可 null無序舊代碼維護
TreeMap紅黑樹否Key 不可 nullKey 自然序/定製序範圍查詢、有序遍歷

並發環境選型決策樹

  1. 單線程 / 線程封閉 → 直接用非同步集合(ArrayList, HashMap)
  2. 多線程只讀、極少寫 → Collections.unmodifiableXxx + 非同步集合
  3. 多線程讀寫並存:
    • 低競爭、兼容舊代碼 → Collections.synchronizedXxx 包裝
    • 高併發、追求吞吐 → 並發包:ConcurrentHashMap, CopyOnWriteArrayList, ConcurrentLinkedQueue
    • 需複合操作原子性 → 顯式鎖或 ConcurrentHashMap.computeIfAbsent 等原子方法

擴容機制深度對比

  • ArrayList:1.5 倍 (old*3/2+1),平衡空間與拷貝頻率
  • Vector:2 倍 (或 capacityIncrement),空間浪費大
  • HashMap:負載因子 0.75 觸發 2 倍擴容,JDK 8 引入紅黑樹化解鏈表過長

遍歷最佳實踐

// List 首選 for-each / 索引循環
for (String s : list) { ... }
for (int i = 0; i < list.size(); i++) { ... }

// Map 三種遍歷
for (Map.Entry<K,V> e : map.entrySet()) { ... }  // 推薦:單次查找同時拿 K/V
for (K k : map.keySet()) { V v = map.get(k); }   // 兩次查找,稍慢
for (V v : map.values()) { ... }                 // 只需值

// 並發安全遍歷
ConcurrentHashMap: 直接 for-each entrySet(),弱一致性迭代器
CopyOnWriteArrayList: 直接 for-each,遍歷快照

常見坑點避雷

  1. HashMap 多線程 put 導致死循環 (JDK 7 擴容鏈表成環) → 改用 ConcurrentHashMap
  2. 遍歷時修改拋 ConcurrentModificationException → 迭代器 remove() / 並發集合 / 加鎖
  3. 自定義 Key 未重寫 hashCode/equals → 邏輯錯誤,get 取不到值
  4. ArrayList 作為 Queue 用 add/remove(0) → O(n) 位移,改用 LinkedList 或 ArrayDeque

面試高頻口訣

查找快用 ArrayList,增刪快用 LinkedList;單線程用非同步,多線程用並發包;Key 要重寫雙方法,遍歷用 entrySet 最快。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved