2、HashMap 到底有多少个坑?面试官问了都不敢下手

90 阅读2分钟

今天我们聊聊最常被提问、最容易踩坑、最像“背刺工具”的一个类:

java
复制编辑
java.util.HashMap

小白用它存键值对,专家用它判断你是否配得上大厂 offer。


1️⃣ HashMap 的基础:看似简单

新手眼里的 HashMap:
✅ put 存值,get 取值
✅ 初始容量 16,负载因子 0.75
✅ key 不允许重复,value 可以重复

但问题来了:为什么负载因子是 0.75?扩容是怎么做的?为什么 JDK8 改用了红黑树?

image.png


2️⃣ 深入:HashMap 设计细节

熟手应该知道的:
✅ HashMap 的核心是数组 + 链表(JDK7)或数组 + 链表/红黑树(JDK8)
✅ key 的 hashCode 决定存放位置,equals 决定是否相同
✅ 扩容机制:当 size > capacity × loadFactor 时,数组扩容为原来的 2 倍,重新 rehash
✅ 链表长度 > 8 且数组容量 ≥ 64 时,链表转为红黑树(JDK8)

小故事:

面试官:“为什么需要红黑树优化?”
候选人:“因为链表太长会退化成 O(n) 查询。”
面试官:“那什么时候退化?”
候选人:“呃……好像没细看。”
(凉了)


3️⃣ 常见的 HashMap 坑

⚠ 多线程环境下直接用 HashMap → 可能死循环、数据丢失(用 ConcurrentHashMap!)
⚠ 键对象 hashCode 写得不对(或未重写 equals) → 查询不到、重复存入
⚠ 忘记考虑扩容时的 rehash 开销 → 性能突然下降
⚠ 自定义 key 用了可变对象(如修改了对象字段)→ key 找不到了

搞笑例子:

用 HashMap 做抽奖池,结果因为自定义对象没重写 equals,出现了重复中奖,老板以为你在作弊。


4️⃣ 小总结

HashMap 看似简单,但背后:
✅ 数据结构(数组 + 链表/红黑树)
✅ 哈希算法(扰动函数、hashCode、equals)
✅ 扩容机制(rehash、负载因子)
✅ 并发安全(非线程安全!)

只有理解这些,你才能写出稳健的代码,才能在面试中从容应对。


彩蛋:面试幽默问答

面试官:“你知道 HashMap 是线程安全的吗?”
你:“线程安全?当然不是,不然要 ConcurrentHashMap 干嘛!”
面试官笑着点头:“好,你至少没掉坑。”