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

Java Map 集合總結:HashMap、Hashtable、TreeMap、WeakHashMap 核心差異與場景選型

     編輯:Java 相關知識

一、Map 介面體系總覽

Map (I)
 ├─ AbstractMap          // 骨架實現
 │    ├─ HashMap         // 拉鏈法雜湊表,非同步,允許 null
 │    ├─ LinkedHashMap   // 繼承 HashMap,雙向鏈表保序
 │    ├─ TreeMap         // 紅黑樹,有序,NavigableMap
 │    ├─ WeakHashMap     // 弱鍵引用,GC 自動清理
 │    ├─ IdentityHashMap // == 比較而非 equals
 │    └─ EnumMap         // Enum 鍵專用,位向量
 ├─ Hashtable            // 繼承 Dictionary,同步,不允許 null
 └─ ConcurrentHashMap    // JUC,分段鎖/CAS,高併發

二、四大經典實現深度對比

維度HashMapHashtableTreeMapWeakHashMap
底層結構拉鏈法雜湊表 (JDK8+ 鏈表轉紅黑樹)拉鏈法雜湊表紅黑樹拉鏈法雜湊表 (弱鍵)
線程安全否是 (全鎖 synchronized)否否
null 鍵/值允許 (1 null key)禁止值允許,鍵禁止允許
順序無序無序有序 (自然/Comparator)無序
遍歷方式IteratorIterator + EnumerationIteratorIterator
擴容策略2倍 (16→32...)2倍+1 (11→23...)無擴容 (樹增長)同 HashMap
雜湊算法擾動函數 (高位混合)直接 key.hashCode()比較器 compare()同 HashMap
序列化支援支援支援不支援 (無 Serializable)
克隆支援支援支援不支援 (無 Cloneable)
核心優勢單線程高效通用舊代碼兼容、線程安全有序、區間/導航查詢鍵自動失效、緩存、監聽器

三、HashMap vs Hashtable 關鍵差異補充

  • 同步粒度:Hashtable 所有方法 synchronized,吞吐極低;高併發請用 ConcurrentHashMap。
  • 雜湊擾動:HashMap 使用 hash(key.hashCode()) 將高位資訊混合到低位,減少碰撞;Hashtable 直接用 hashCode()。
  • 遍歷順序:HashMap 陣列 0→N;Hashtable 陣列 N→0(歷史包袱)。
  • contains(value):Hashtable 有,HashMap 無 (需 containsValue)。

四、WeakHashMap 獨特機制

適用場景

  • 鍵為「弱引用」,當鍵無強引用被 GC 回收時,條目自動移除。
  • 典型:類級緩存(ClassLoader 卸載自動清理)、監聽器映射(監聽器被回收自動移除)。

內部原理

// 核心:Entry 繼承 WeakReference
static class Entry extends WeakReference implements Map.Entry {
    V value;
    Entry(K k, V v, ReferenceQueue q, int h, Entry next) {
        super(k, q); // 註冊到 ReferenceQueue
        value = v;
    }
}

// 每次操作先清理隊列
private void expungeStaleEntries() {
    for (Entry e; (e = (Entry) queue.poll()) != null; ) {
        int i = indexFor(e.hash, table.length);
        Entry prev = table[i], curr = prev;
        while (curr != e) { prev = curr; curr = curr.next; }
        prev.next = curr.next; // 從鏈表移除
    }
}

注意

  • Value 為強引用,若 Value 間接引用 Key 會阻礙回收。
  • 非線程安全,併發用 Collections.synchronizedMap 或自定義。

五、選型決策指南

  1. 單線程通用、高效去重/查找 → HashMap (預設 16/0.75,預估大小用構造函數)。
  2. 需要有序/區間查詢/導航 → TreeMap (或併發 ConcurrentSkipListMap)。
  3. 保持插入/訪問順序 → LinkedHashMap (LRU 快取設 accessOrder=true 並覆寫 removeEldestEntry)。
  4. 多線程高併發 → ConcurrentHashMap (JDK8+ CAS+synchronized 細粒度,無鎖讀)。
  5. 鍵需自動失效 (緩存、監聽器) → WeakHashMap。
  6. 鍵為 Enum → EnumMap (極致效能、記憶體)。
  7. 身份比較 (==) → IdentityHashMap (序列化、圖算法)。
  8. 舊代碼維護 → Hashtable (新代碼禁用)。

六、效能調優清單

  • 預估容量:new HashMap<>((int)(expectedSize/0.75f) + 1) 避免 Rehash。
  • Key 類覆寫 hashCode/equals,高質量雜湊減少碰撞。
  • 避免在迭代中修改結構 (Fail-Fast);需修改用 iterator.remove() 或 computeIfAbsent 等原子操作。
  • 大量批量寫入考慮 putAll 或並行流 (JDK8+)。

七、總結

Map 選型核心三問:需不需要有序?需不需要線程安全?鍵需不需要自動過期?
HashMap 通用王者,TreeMap 有序導航,ConcurrentHashMap 併發首選,WeakHashMap 自動清理神器。
Hashtable 退役,LinkedHashMap 保序利器,EnumMap/IdentityMap 專用神器。

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