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

面試必備:HashMap 與 Hashtable 核心區別深度解析

     編輯:Java 綜合教學

HashMap vs Hashtable:從源碼到實戰的全方位對比

作為 Java 集合框架中最經典的面試題,HashMap 與 Hashtable 的區別不僅在於「線程安全」與「允許 null」,更體現在繼承體系、擴容機制、哈希計算等底層細節。本文結合 JDK 源碼(以 JDK 8 為參考),為你拆解核心差異。

1. 類繼承體系不同

特性HashMapHashtable
父類AbstractMapDictionary(舊集合類)
實現接口Map, Cloneable, SerializableMap, Cloneable, Serializable

2. 同步與線程安全

  • Hashtable:所有公共方法均加 synchronized,線程安全但性能較低。
  • HashMap:非同步,高性能。多線程環境下可用 Collections.synchronizedMap() 包裝,或改用 ConcurrentHashMap。

3. Null 鍵值支持

  • HashMap:允許 null key(最多一個)與 null value。
  • Hashtable:put 時若 key 或 value 為 null 直接拋 NullPointerException。

4. 源碼關鍵差異(JDK 8 視角)

Hashtable.put()

public synchronized V put(K key, V value) {
    if (value == null) throw new NullPointerException(); // 不允許 null value
    int hash = key.hashCode(); // key 不能為 null,否則 NPE
    int index = (hash & 0x7FFFFFFF) % tab.length;
    // ... 遍歷鏈表覆蓋或插入 ...
}

HashMap.put()

public V put(K key, V value) {
    if (key == null) return putForNullKey(value); // 允許 null key
    int hash = hash(key.hashCode()); // 經過擾動函數二次哈希
    int i = indexFor(hash, table.length);
    // ... 遍歷鏈表/紅黑樹覆蓋或插入 ...
}

5. 其他重要差異

  • contains 方法:Hashtable 有 contains(Object value) 易混淆,HashMap 移除,改用 containsValue() 和 containsKey()。
  • 迭代器:HashMap 迭代器是 fail-fast(修改計數器 modCount),Hashtable 的 Enumeration 不是。
  • 初始容量與擴容:HashMap 默認 16,擴容 2 倍(冪次方);Hashtable 默認 11,擴容 2n+1(質數偏好)。
  • 哈希計算:HashMap 引入 hash(Object key) 擾動函數(高 16 位參與運算),減少碰撞;Hashtable 直接用 key.hashCode()。

6. 總結對比表

維度HashMapHashtable
線程安全否是(synchronized)
允許 null key/value是否
父類AbstractMapDictionary
性能高較低
推薦場景單線程、或配合 ConcurrentHashMap舊代碼維護,極少新建

最佳實踐建議

  1. 新代碼優先使用 HashMap(單線程)或 ConcurrentHashMap(多線程)。
  2. 避免在多線程中直接操作 HashMap,若需同步用 Collections.synchronizedMap(new HashMap<>())。
  3. 初始化時指定容量 new HashMap<>(expectedSize) 減少擴容開銷。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved