【HashMap原理演示】
作为程序员面试必考题,HashMap的原理几乎每次都会被问到。今天咱们就用人话拆解它,保证听完就能跟面试官唠明白!先送个福利:2025年Java面试宝典(含HashMap高频题) 👉 网盘下载(提取码:9b3g)
🔍 一、HashMap是啥?它咋工作的?
你可以把HashMap想象成一排桶(数组),每个桶里挂着链条(链表)或小树(红黑树)。存数据时,它用key的hashCode() 计算桶位置(哈希桶索引),再把键值对挂到桶里。
举个栗子🌰:
map.put("Java", 999)
- 对
"Java"调用hashCode()→ 得到哈希值 - 哈希值对桶数组长度取模 → 确定桶位置
- 把
<"Java", 999>挂到这个桶的链条上

(就像把书放进编号的书架格子!)
⚡ 二、PUT操作内部咋流转?
当你说map.put(key, value)时,HashMap在后台干了这些事:
- 计算桶下标:
(n - 1) & hash(n=桶数组长度) - 检查桶是否空:
✅ 空的 → 直接新建节点放入
❌ 非空 → 挨个比链条上的key(先比hash,再比equals()) - 发现相同key → 覆盖旧value
- 没找到相同key → 新节点挂链条末尾
- 触发扩容检查:当元素数量超过
容量*负载因子(默认0.75) → 开启扩容
🔥 三、为啥会哈希碰撞?HashMap咋解决?
不同key算出相同桶位置就是哈希冲突(比如"Aa"和"BB"的hashCode都是2112)。HashMap用两种招数应对:
✅ 拉链法:桶挂链表(JDK7前只用这招)
✅ 链表转红黑树(JDK8+优化):当链表长度≥8且桶数组≥64时,链表变红黑树,查询从O(n)→O(logn)

📦 四、HashMap扩容是个啥流程?
当元素数超过容量*0.75(比如默认16*0.75=12),就会双倍扩容:
- 新建一个2倍大的桶数组
- 重新哈希所有元素:老数组每个桶的节点,重新计算在新数组的位置
- 并发操作会死循环:这也是为啥HashMap线程不安全!
扩容后元素位置变化规律:
新位置 = 原位置 或 原位置+原容量
(比如原来在桶5,扩容后可能在5或5+16=21号桶)
⚠️ 五、面试常踩的坑
- 线程不安全:并发put可能丢数据甚至死循环 → 用
ConcurrentHashMap - key对象需重写hashCode()和equals():
- 没重写
hashCode()→ 相同对象可能进不同桶 - 没重写
equals()→ 覆盖value会失效
- 没重写
- 为啥用红黑树不用AVL树? 红黑树插入更快,虽查询稍慢,但综合更优
💡 六、HashMap使用小贴士
- 预估数据量:初始化时设好容量避免频繁扩容(如
new HashMap<>(1024)) - 选不可变对象做key:比如String、Integer,防止修改key导致hash变化
- 避免高频更新大HashMap:扩容成本高,考虑其他结构
最后安利个神器👉 面试鸭会员 刷题超方便!通过面试鸭返利网找我开通可返25元,直接省顿饭钱~(暗示:提我名字有惊喜😉)

懂了HashMap原理,面试时被问到底层实现,你就能拍胸脯说:"这题我会!" ✨


