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

Java 集合框架全景圖譜:List/Set/Map 體系、Fail-Fast 機制與 CopyOnWrite 解決方案

     編輯:Java 綜合教學

集合框架核心結構

Java Collections Framework 以 Collection 和 Map 為雙根,提供統一操作接口:

Collection (I)
├── List (I)          有序、可重複
│   ├── ArrayList     動態數組、隨機訪問快
│   ├── LinkedList    雙向鏈表、增刪快、實現 Deque
│   ├── Vector        同步、已過時
│   └── Stack         LIFO、繼承 Vector
└── Set (I)           唯一性
    ├── HashSet       HashMap 底層、無序
    ├── LinkedHashSet 保持插入順序
    └── TreeSet       紅黑樹、有序、O(log n)

Map (I)
├── HashMap           數組+鏈表/紅黑樹、非同步
├── LinkedHashMap     保持插入/訪問順序
├── TreeMap           紅黑樹、有序鍵
├── Hashtable         同步、已過時
├── WeakHashMap       弱鍵、GC 自動清理
└── ConcurrentHashMap 分段鎖/CAS、高併發

List 選型決策樹

場景推薦理由
頻繁隨機訪問、少量增刪ArrayList底層數組、O(1) 訪問
頻繁頭尾增刪、作為隊列/棧LinkedList鏈表結構、O(1) 首尾操作
單線程/線程封閉ArrayList無同步開銷、性能最優
多線程共享、低併發Vector / Collections.synchronizedList方法級同步
多線程共享、高併發讀多寫少CopyOnWriteArrayList寫時復制、讀無鎖

Fail-Fast 機制深度解析

觸發條件

迭代過程中,集合結構被修改(add/remove/clear 導致 modCount 變化),Iterator.next() 檢測到 expectedModCount != modCount 拋出 ConcurrentModificationException。

源碼級還原

// AbstractList.iterator()
public Iterator iterator() {
    return new Itr(); // 內部類,捕獲 expectedModCount = modCount
}

private class Itr implements Iterator {
    int cursor, lastRet = -1;
    int expectedModCount = modCount; // 快照
    
    public E next() {
        checkForComodification(); // 核心檢查
        // ...
    }
    
    final void checkForComodification() {
        if (modCount != expectedModCount)
            throw new ConcurrentModificationException();
    }
}

多線程下的必現場景

List list = new ArrayList<>();
// 線程 A 遍歷
new Thread(() -> {
    for (Integer i : list) { /* 讀 */ }
}).start();
// 線程 B 修改
new Thread(() -> {
    list.add(999); // modCount++,線程 A 下次 next() 必拋異常
}).start();

CopyOnWriteArrayList:讀寫分離終極方案

核心原理

  • 讀操作:直接訪問當前數組,無鎖、無檢查、極快
  • 寫操作:ReentrantLock 加鎖 → 復制新數組 → 修改 → volatile 切換引用
  • 迭代器:構建時快照當前數組,遍歷快照,不檢查 modCount
// COWIterator 簡化版
static final class COWIterator implements ListIterator {
    private final Object[] snapshot; // 構建時快照
    private int cursor;
    
    COWIterator(Object[] elements) {
        this.snapshot = elements; // 無 expectedModCount!
    }
    public boolean hasNext() { return cursor < snapshot.length; }
    public E next() { return (E) snapshot[cursor++]; }
    // 無 checkForComodification()!
}

適用與不適用場景

適用不適用
讀多寫少(緩存、監聽器列表、配置)寫多場景(頻繁復制數組、GC 壓力大)
遍歷時允許見到舊數據(最終一致)需實時強一致性遍歷
集合較小(<1000 元素)大集合寫入(復制開銷 O(n))

Map 體系精華

  • HashMap:JDK 8 引入紅黑樹退化鏈表、擴容優化、putVal 核心邏輯
  • ConcurrentHashMap:JDK 7 分段鎖 → JDK 8 CAS+synchronized 節點、size() LongAdder
  • TreeMap:紅黑樹、NavigableMap 接口(floor/ceiling/higher/lower)
  • WeakHashMap:Key 為弱引用、Entry 繼承 WeakReference、GC 時自動清理

Iterator vs Enumeration

特性IteratorEnumeration
方法hasNext/next/removehasMoreElements/nextElement
刪除支持支持不支持
Fail-Fast支持不支持
性能略慢(檢查開銷)略快
適用現代代碼、需安全刪除舊 API(Vector/Hashtable/Properties)

實戰建議

  1. 優先 ArrayList/HashMap/HashSet,按需升級
  2. 多線程寫入用 ConcurrentHashMap/CopyOnWriteArrayList
  3. 遍歷中需刪除 → Iterator.remove() 或 list.removeIf() (JDK 8)
  4. 避免在循環中調用 size() 等同步方法
  5. 集合作為方法參數/返回值 → 使用接口類型(List 而非 ArrayList)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved