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

Java Map 體系深度對比:HashMap、Hashtable、HashSet 核心差異

     編輯:Java 相關知識

Map 與 Set 是 Java 集合框架兩大支柱。本文聚焦 HashMap、Hashtable、HashSet 三者的繼承體系、線程安全、空值策略、遍歷方式、哈希計算、擴容機制七大核心差異。

七大核心差異對比表

維度HashtableHashMapHashSet
繼承父類DictionaryAbstractMapAbstractSet (內部用 HashMap)
實現介面MapMapSet
線程安全同步(方法級 synchronized)非同步非同步
允許 nullKey/Value 皆不允許1 個 null Key,多個 null Value1 個 null 元素
contains 方法contains / containsKey / containsValuecontainsKey / containsValue(無 contains)contains
遍歷方式Iterator + Enumeration(歷史包袱)IteratorIterator
哈希值計算直接用 key.hashCode()扰動函數重新計算(高位混合低位)同 HashMap
初始容量/擴容11,old*2+116(2^n),2倍擴容同 HashMap

深度解析關鍵差異

1. 線程安全選型

  • Hashtable:方法級鎖,粒度粗,效能低,**新代碼不推薦**
  • Collections.synchronizedMap(new HashMap()):包裝器,同樣粗粒度
  • ConcurrentHashMap:JDK 8 CAS + synchronized 節點鎖 + 紅黑樹,**首選併發 Map**

2. null 值語義陷阱

Map<String, String> map = new HashMap<>();
map.put("key", null);
map.get("key"); // 回傳 null
map.get("nonexistent"); // 也回傳 null
// 無法區分「值為 null」vs「Key 不存在」
map.containsKey("key"); // 必須用此判斷

3. 哈希擾動函數(HashMap 核心優化)

// JDK 1.8 靜態擾動函數
static final int hash(Object key) {
    int h;
    return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
// 將高 16 位與低 16 位異或,減少碰撞,提升分佈均勻度

Hashtable 直接使用 hashCode(),高位資訊浪費,碰撞率較高。

4. 擴容機制差異

  • Hashtable:newCapacity = oldCapacity * 2 + 1(保持奇數,略減碰撞)
  • HashMap:newCapacity = oldCapacity << 1(保持 2 的冪次,配合 (n - 1) & hash 位運算取模,極快)

HashSet 實現本質

HashSet 內部持有一個 HashMap<E, Object>,所有元素作為 Key 存入,Value 統一為 PRESENT = new Object()。因此特性與 HashMap 高度一致。

WeakHashMap 補充

Key 為弱引用,GC 時自動清理無強引用的 Key,適合元數據快取。同樣非同步。

選型建議

  • 單線程、高效 Map:HashMap
  • 多線程併發 Map:ConcurrentHashMap
  • 需同步、舊系統維護:Hashtable(或包裝器)
  • 去重集合、無序:HashSet
  • 有序集合:LinkedHashSet(插入序)/ TreeSet(自然序)
  • Key 生命週期自動管理:WeakHashMap
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved