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

Java 集合框架深度總結:List、Set、Map 核心實現、源碼級解析與選型指南

     編輯:Java 程式設計入門

集合體系宏觀圖譜

java.util 集合根接口:Collection(單列)與 Map(雙列)。Collection 下分 List(有序、可重複)、Set(無序、唯一)、Queue(佇列)。并發集合位於 java.util.concurrent。

集合 UML 圖譜

一、Collection 公共操作

Collection<Integer> c = new ArrayList<>();
c.add(1); c.addAll(List.of(2,3));
c.contains(1); c.containsAll(List.of(1,2));
c.remove(1); c.removeAll(List.of(2,3));
c.retainAll(List.of(1)); // 交集
c.clear(); c.isEmpty(); c.size();
Object[] arr = c.toArray(); // 或 c.toArray(new Integer[0])
Iterator<Integer> it = c.iterator(); // 唯一遍歷方式
// foreach 底層調用 iterator()
for (Integer i : c) { ... }

二、List 族群:有序可重複

實現底層結構線程安全隨機訪問插入刪除典型場景
ArrayList動態數組否O(1) ✓尾部 O(1),中間 O(n)默認首選,頻繁讀、少寫
LinkedList雙向鏈表否O(n) ✗首尾 O(1),中間 O(n)頻繁首尾增刪、佇列/棧
Vector動態數組是 (synchronized)O(1)同 ArrayList遺留代碼,性能差,推薦 Collections.synchronizedList 或 CopyOnWriteArrayList
CopyOnWriteArrayList數組 + COW是 (寫時復制)O(1)O(n) 複制整個數組讀多寫少、遍歷佔比高、無鎖讀

ArrayList 擴容機制

默認初始容量 10,擴容 1.5 倍(newCapacity = oldCapacity + (oldCapacity >> 1))。ensureCapacity 可預分配減少拷貝。

LinkedList 實現 Deque

Deque<String> deque = new LinkedList<>();
deque.addFirst("a"); deque.addLast("b");
deque.push("c"); // 棧
deque.pop();
deque.offer("d"); // 隊列
deque.poll();

三、Set 族群:唯一性

實現底層有序性Null 支持線程安全時間複雜度
HashSetHashMap無序允許 1 個否O(1)
LinkedHashSetLinkedHashMap插入序允許 1 個否O(1)
TreeSetTreeMap (紅黑樹)自然序/Comparator不允許否O(log n)
CopyOnWriteArraySetCOW ArrayList插入序允許是O(n)
ConcurrentSkipListSet跳表自然序不允許是O(log n)

HashSet 去重原理

依賴 hashCode() 定桶位,equals() 精確比較。不可變對象作為元素最安全。若元素可變且參與 hashCode/equals,修改後會導致「找不到元素」。

class MyKey { int id; @Override public boolean equals(Object o) { return this.id == ((MyKey)o).id; } @Override public int hashCode() { return id; } }

TreeSet 定制排序

Set<Student> set = new TreeSet<>(Comparator.comparing(Student::getScore).reversed()
    .thenComparing(Student::getName));
set.add(new Student("A", 90));
set.add(new Student("B", 90)); // 同分按名字序

四、Map 族群:鍵值映射

實現底層有序性Null Key/Value線程安全JDK 8+ 優化
HashMap數組+鏈表/紅黑樹無序允許 1 null key,多 null value否鏈表轉紅黑樹 (TREEIFY_THRESHOLD=8)
LinkedHashMapHashMap + 雙向鏈表插入序/訪問序允許否支持 LRU (accessOrder=true)
Hashtable數組+鏈表無序不允許 null是 (synchronized)無
TreeMap紅黑樹自然序/Comparator不允許 null key否無
ConcurrentHashMap數組+鏈表/紅黑樹 + CAS/synchronized無序不允許 null是 (分段鎖/細粒度鎖)JDK 8 放棄 Segment,採用 Node 首節點 CAS + synchronized
ConcurrentSkipListMap跳表自然序不允許 null是無鎖範圍查詢

HashMap 核心參數

  • loadFactor (默認 0.75):空間換時間,過大導致碰撞,過小浪費空間。
  • threshold = capacity * loadFactor:觸發擴容門檻。
  • JDK 8 鏈表長度 ≥ 8 且容量 ≥ 64 → 紅黑樹;≤ 6 退化鏈表。

ConcurrentHashMap 進化史

JDK 7:Segment 分段鎖(默認 16 段),寫鎖段,讀無鎖(volatile)。
JDK 8+:放棄 Segment,採用 synchronized (tab[i]) 鎖首節點 + CAS 操作,細粒度更細,擴容支持多線程協助 (ForwardingNode)。

五、工具類與最佳實踐

Collections 工具方法

List<String> unmod = Collections.unmodifiableList(list); // 只讀視圖
List<String> sync = Collections.synchronizedList(new ArrayList<>()); // 同步包裝
List<String> empty = Collections.emptyList(); // 共享空列表
Collections.shuffle(list); // 洗牌
Collections.sort(list, Comparator.naturalOrder()); // 排序
int idx = Collections.binarySearch(sortedList, key); // 二分查找

Java 9+ 不可變集合工廠

List.of("a", "b"); Set.of(1,2,3); Map.of("k1",1,"k2",2); Map.ofEntries(entry("k1",1), entry("k2",2));

選型決策樹

  1. 需要 Key-Value → Map:高並發用 ConcurrentHashMap,需排序用 TreeMap,需 LRU 用 LinkedHashMap。
  2. 單列數據 → List/Set/Queue:
      li>頻繁隨機訪問、尾部增刪 → ArrayList
    • 頻繁首尾增刪、佇列/棧 → LinkedList / ArrayDeque
    • 去重 → HashSet (無序) / LinkedHashSet (插入序) / TreeSet (排序)
    • 多線程寫多 → CopyOnWriteArrayList/Set (讀多寫少) / ConcurrentHashMap.newKeySet()
    • 高並發佇列 → ArrayBlockingQueue / LinkedBlockingQueue / ConcurrentLinkedQueue

六、常見面試陷阱

問題陷阱正解
ArrayList vs VectorVector 線程安全就用它Vector 鎖粒度粗、擴容 2 倍、已淘汰;用 Collections.synchronizedList 或 CopyOnWriteArrayList
HashMap 多線程 put死循環 (JDK 7 擴容鏈表倒序)JDK 8 不會死循環但會數據丟失/覆蓋;必須用 ConcurrentHashMap
遍歷時刪除for-each 中 remove → ConcurrentModificationException用 Iterator.remove() / ListIterator / removeIf / Stream.filter
Map 遍歷方式keySet 循環 getentrySet 遍歷 / forEach((k,v)->...) / keySet 只有 key 時
Arrays.asList以為可增刪返回固定長度 List,增刪拋異常;用 new ArrayList<>(Arrays.asList(...))

總結

Java 集合框架設計精妙,掌握底層數據結構(數組、鏈表、紅黑樹、哈希表、跳表)、擴容機制、線程安全策略,能寫出高性能、無 Bug 的業務代碼。日常開發首選 ArrayList、HashMap、HashSet、ArrayDeque,並發場景首選 ConcurrentHashMap、CopyOnWriteArrayList、ConcurrentLinkedQueue,善用 Collections、Stream、List.of 簡化代碼。

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