HashMap和HashTable有什么区别?其底层实现是什么?

HashMap 和 HashTable 是 Java 中两种常用的键值对存储结构,它们都实现了 Map 接口,但在特性、性能和底层实现上有显著的区别。下面我们从多个方面详细对比它们的区别,并深入分析它们的底层实现。


1. 定义

特性HashMapHashTable
定义基于哈希表实现的键值对存储结构。基于哈希表实现的键值对存储结构。
线程安全非线程安全。线程安全(方法使用 synchronized 修饰)。
继承关系继承自 AbstractMap继承自 Dictionary(已过时)。

2. 主要区别

特性HashMapHashTable
线程安全非线程安全。线程安全。
性能较高(无同步开销)。较低(有同步开销)。
允许 null 键/值允许 null 键和 null 值。不允许 null 键和 null 值。
迭代器使用 Iterator,支持快速失败(fail-fast)。使用 Enumeration,不支持快速失败。
初始容量和扩容默认初始容量 16,扩容时容量翻倍。默认初始容量 11,扩容时容量翻倍加 1。
继承关系继承自 AbstractMap继承自 Dictionary(已过时)。

3. 示例代码

HashMap 示例:
Map<String, Integer> hashMap = new HashMap<>();
hashMap.put("A", 1);
hashMap.put("B", 2);
hashMap.put(null, 3); // 允许 null 键
hashMap.put("C", null); // 允许 null 值
System.out.println(hashMap); // 输出 {A=1, B=2, null=3, C=null}
HashTable 示例:
Map<String, Integer> hashTable = new Hashtable<>();
hashTable.put("A", 1);
hashTable.put("B", 2);
// hashTable.put(null, 3); // 报错,不允许 null 键
// hashTable.put("C", null); // 报错,不允许 null 值
System.out.println(hashTable); // 输出 {A=1, B=2}

4. 底层实现

(1) 数据结构
  • HashMap 和 HashTable 的底层都是基于哈希表实现的。

  • 哈希表的核心是一个数组(table),数组的每个元素是一个链表或红黑树(Java 8 之后,当链表长度超过阈值时会转换为红黑树)。

(2) 哈希冲突
  • 当两个键的哈希值相同时,会发生哈希冲突。

  • 冲突的键值对会存储在同一个桶(Bucket)中,形成链表或红黑树。

(3) 扩容机制
  • 当元素数量超过容量与负载因子的乘积时,会触发扩容。

  • HashMap 和 HashTable 的扩容机制类似,但初始容量和扩容策略略有不同:

    • HashMap:默认初始容量 16,扩容时容量翻倍。

    • HashTable:默认初始容量 11,扩容时容量翻倍加 1。


5. 详细对比

(1) 线程安全性
  • HashMap

    • 非线程安全。

    • 如果需要线程安全,可以使用 Collections.synchronizedMap(new HashMap<>()) 或 ConcurrentHashMap

  • HashTable

    • 线程安全,所有方法都用 synchronized 修饰。

    • 由于同步开销,性能较低。

(2) 允许 null 键/值
  • HashMap

    • 允许 null 键和 null 值。

hashMap.put(null, 1); // 允许
hashMap.put("A", null); // 允许

HashTable

  • 不允许 null 键和 null 值。

hashTable.put(null, 1); // 报错
hashTable.put("A", null); // 报错
(3) 迭代器
  • HashMap

    • 使用 Iterator,支持快速失败(fail-fast)。

    • 如果在迭代过程中修改了集合(除了通过 Iterator 的 remove 方法),会抛出 ConcurrentModificationException

  • HashTable

    • 使用 Enumeration,不支持快速失败。

    • 如果在迭代过程中修改了集合,不会抛出异常。

(4) 性能
  • HashMap

    • 由于没有同步开销,性能较高。

  • HashTable

    • 由于所有方法都用 synchronized 修饰,性能较低。


6. 使用场景

场景HashMapHashTable
单线程环境适合。不适合(性能较低)。
多线程环境不适合(需额外同步)。适合(线程安全)。
需要允许 null 键/值适合。不适合。
需要快速失败机制适合。不适合。

7. 总结

特性HashMapHashTable
线程安全非线程安全。线程安全。
性能较高。较低。
允许 null 键/值允许。不允许。
迭代器支持快速失败。不支持快速失败。
初始容量和扩容默认 16,扩容翻倍。默认 11,扩容翻倍加 1。
继承关系继承自 AbstractMap继承自 Dictionary(已过时)。

8. 一句话总结

  • HashMap:非线程安全,性能高,允许 null 键/值,适合单线程环境。

  • HashTable:线程安全,性能低,不允许 null 键/值,适合多线程环境。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EthanMilk

你的鼓励是我创作的最大动力谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值