Hashtable 与 HashMap 的区别(结合 Java 底层源码分析)
1. 线程安全性
-
Hashtable
所有公开方法通过synchronized实现线程安全:// Hashtable 源码片段 (JDK 1.8) public synchronized V put(K key, V value) { ... } public synchronized V get(Object key) { ... }每次操作锁住整个表,高并发下性能差。
-
HashMap
非线程安全,无同步机制:// HashMap 源码片段 (JDK 1.8) public V put(K key, V value) { ... } // 无 synchronized需手动同步(如
Collections.synchronizedMap)或使用ConcurrentHashMap。
2. Null 键值处理
-
Hashtable
不允许 null 键或值,否则抛NullPointerException:public synchronized V put(K key, V value) { if (value == null) throw new NullPointerException(); // 值检查 int hash = key.hashCode(); // 若 key=null 此处抛 NPE ... } -
HashMap
允许一个 null 键和多个 null 值,特殊处理 null 键:static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); // 处理 null }
3. 哈希算法与冲突解决
-
初始容量与扩容
-
Hashtable
默认容量 11,扩容公式:新容量 = 旧容量 * 2 + 1int newCapacity = (oldCapacity 1) + 1; // 位运算优化 -
HashMap
默认容量 16(2 的幂),扩容公式:新容量 = 旧容量 * 2newCap = oldCap 1; // 保证容量始终为 2^n
-
-
哈希计算
-
Hashtable 直接使用对象的
hashCode():int hash = key.hashCode(); int index = (hash & 0x7FFFFFFF) % table.length; // 取模运算 -
HashMap 优化哈希分布(扰动函数):
static final int hash(Object key) { int h; return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); // 高位异或 } // 计算索引: (n-1) & hash
-
-
冲突解决
两者均使用 链表法,但 HashMap 在 Java 8 引入红黑树优化:// HashMap 链表转树阈值 (TREEIFY_THRESHOLD = 8) if (binCount >= TREEIFY_THRESHOLD - 1) treeifyBin(tab, hash);
4. 迭代器设计
-
Hashtable
使用Enumeration遍历,不支持快速失败(Fail-Fast)机制:public EnumerationK> keys() { return getEnumeration(KEYS); } -
HashMap
使用Iterator并支持 Fail-Fast:final class KeyIterator extends HashIterator implements IteratorK> { public final K next() { return nextNode().key; } }迭代时检测
modCount,若结构被修改则抛ConcurrentModificationException。
5. 继承体系
-
Hashtable
继承陈旧的Dictionary类:public class HashtableK,V> extends DictionaryK,V> ... -
HashMap
继承现代的AbstractMap类:public class HashMapK,V> extends AbstractMapK,V> ...
总结对比表
| 特性 | Hashtable | HashMap |
|---|---|---|
| 线程安全 | 是(同步方法) | 否(需外部同步) |
| Null 键值 | 禁止 | 允许一个 null 键和多个 null 值 |
| 初始容量 | 11 | 16(2^n) |
| 扩容机制 | 旧容量*2 + 1 |
旧容量*2 |
| 哈希计算 | 直接取模 hash % length
|
(n-1) & hash(位运算优化) |
| 冲突解决 | 链表 | 链表 + 红黑树(JDK8+) |
| 迭代器 | Enumeration(非快速失败) | Iterator(支持 Fail-Fast) |
| 继承类 | Dictionary | AbstractMap |
| 性能 | 低(同步开销) | 高 |
使用建议
-
单线程环境:优先使用
HashMap(更高性能)。 -
高并发场景:用
ConcurrentHashMap替代Hashtable(分段锁优化)。 -
遗留系统兼容:需线程安全且不介意性能时再用
Hashtable。
文章来源于互联网:【1.JDK底层源码剖析】2.3HashMap初始容量及扩容机制
相关推荐: 【AI】入门级提示词模板:适用于ChatGPT、文心一言等主流模型
入门级提示词模板:适用于 ChatGPT、文心一言等主流模型 ** 在当下这个人工智能飞速发展的时代,ChatGPT、文心一言等主流大模型已经广泛地融入到我们的工作与生活当中。不管是创作文章、生成代码,还是进行数据分析、获取创意灵感,这些大模型都能展现出令…
5bei.cn大模型教程网










