面试题--HashMap和HashTable的区别

本文对比了HashMap与Hashtable的实现方式及使用场景。介绍了两者的主要区别包括:父类、线程安全性、是否允许null键值等,并对它们的历史背景进行了简单的说明。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

HashMap父类 :AbstractMap

Hashtable父类:Dictiionary

是否同步:HashMap否/Hashtable

kv可否null:HashMap是/Hashtable


HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口。

主要区别在于HashMap允许空(null)键值(key),由于非线程安全,效率上可能高于Hashtable。

 

HashMap允许将null作为一个entry的key或者value,而Hashtable不允许。

 

HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。 

 

Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。

 

最大的不同是,Hashtable的方法是Synchronize的,而HashMap不是,在多个线程访问Hashtable时,不需要自己为它的方法实现同步,而HashMap 就必须为之提供外同步(Collections.synchronizedMap)。 

Hashtable和HashMap采用的hash/rehash都大概一样,所以性能不会有很大的差异。

### 线程安全性 HashMap 是线程不安全的,这意味着在线程环境下,如果个线程同时修改了 HashMap 的结构(例如添加或删除元素),则可能会导致数据不一致的问题。为了在线程环境中使用 HashMap,需要外部同步机制来保证线程安全。相比之下,Hashtable 是线程安全的,它的方法都是 synchronized 的,因此在线程访问时不需要额外的同步措施[^2]。 ### 键值允许为 null 的情况 HashMap 允许键值都为 null,其中键只能有一个 null 值。而在 Hashtable 中,键值都不允许为 null,尝试插入 null 值会导致抛出 NullPointerException 异常。 ### 迭代器差异 HashMap 使用的是 Iterator,这是一种 fail-fast 迭代器,当迭代过程中集合被修改,除了通过迭代器自身的 remove 方法外,会抛出 ConcurrentModificationException 异常。而 Hashtable 使用的是 Enumeration 迭代器,它不是 fail-fast 的,因此在迭代过程中集合被修改不会抛出异常。 ### Hash 计算方式 HashMap 在计算 hash 值时进行了额外的处理,以减少哈希冲突的概率。而 Hashtable 直接使用了 key 的 hashCode 方法来计算 hash 值。 ### 默认初始大小与扩容方式 HashMap 默认初始大小为 16,并且容量必须是 2 的整数次幂,扩容时将容量变为原来的 2 倍。而 Hashtable 默认初始大小为 11,扩容时将容量变为原来的 2 倍加 1[^2]。 ### 是否包含 contains 方法 HashMap 没有 contains 方法,而 Hashtable 包含了类似于 containsValue 的 contains 方法。 ### 继承关系 HashMap 继承自 AbstractMap 类,而 Hashtable 继承自 Dictionary 类[^2]。 ### 数据结构 HashMap 采用数组、链表红黑树的数据结构,而非线程安全且无序,查找效率较高,初始化默认容量为 $2^4$,每次扩容为原来的 2 倍。而 Hashtable 采用数组链表的数据结构,线程安全,键值均不允许为 null,默认初始大小为 11,每次扩充为原来的 $2n+1$[^3]。 ### 同步机制 最大的不同在于 Hashtable 的方法是 synchronized 的,而 HashMap 不是,在个线程访问 Hashtable 时,不需要自己为它的方法实现同步,而 HashMap 就必须提供外同步 (Collections.synchronizedMap)[^4]。 ```java // 示例代码:HashMap 需要外部同步 Map<String, String> map = Collections.synchronizedMap(new HashMap<>()); ``` ### 相关问题 1. 如何在线程环境中安全地使用 HashMap? 2. HashMap Hashtable 在性能上有何差异? 3. Java 中如何实现一个线程安全的 HashMap
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值