第21题:HashMap和Hashtable的区别是什么
📚 回答:
-
相同点:
-
数据结构:
- 在JDK 1.7 及之前,HashMap和Hashtable的底层数据结构均为数组+链表。
- 但在JDK 1.8 中,HashMap引入了红黑树 优化(链表长度≥8时转换),而Hashtable仍保持数组+链表结构。
-
负载因子:
- 两者默认的负载因子都是0.75,用于控制扩容的触发条件。
-
-
不同点:
1. 线程安全性
HashMap是线程不安全的,适合单线程场景。Hashtable是线程安全 的,底层方法基本都用synchronized关键字修饰,适合多线程场景。
2. 对
null的支持-
HashMap允许允许 key 为 null(仅一个),允许 value 为 null。 -
Hashtable不允许key或value为null:- 如果
key为null,会抛出NullPointerException异常。 - 如果
value为null,也会抛出NullPointerException异常。
3. 初始容量与扩容机制
- 如果
-
初始容量:
HashMap的初始容量为16。Hashtable的初始容量为11。
-
扩容规则:
HashMap:当已用容量 > 总容量 × 负载因子时,扩容为当前容量的2倍(2n)。Hashtable:当已用容量 > 总容量 × 负载因子时,扩容为当前容量的2倍加1(2n + 1)。
-
指定初始容量:
HashMap:扩容后容量始终是2的幂次方。Hashtable:直接使用用户指定的容量大小。
💡 面试官视角:
-
面试官可能会问"为什么
HashMap允许null键值而Hashtable不允许?"答:
Hashtable禁止null键值对,主要因为其底层实现直接依赖key.hashCode()和value的操作,null会直接抛NullPointerException(早期设计未做兼容处理);同时禁止null可避免get(key)返回null时的歧义(无法区分key不存在还是value为null)。
HashMap允许null键(通过hash(null)=0特殊处理)和null值,因其设计时考虑了更灵活的场景需求,但需开发者自行通过containsKey()判断键是否存在。 -
面试官可能会追问"如果需要线程安全的
HashMap怎么办?"答:可以使用
Collections.synchronizedMap包装HashMap,或者直接使用ConcurrentHashMap。
📌 专栏 :大白话说Java面试题 --- 01-Java基础篇