news 2026/4/16 16:03:38

Java 面试小册 | HashMap 的 put 方法

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Java 面试小册 | HashMap 的 put 方法

面试官(张姐):哈喽 malog!今天咱们聚焦下 HashMap 的源码细节 —— 这可是 Java 面试的 “必考题”,你平时有没有扒过它的 put 方法流程呀?

malog:张姐好!必须扒过~毕竟写业务代码天天用 HashMap,不搞懂源码总觉得心里没底哈哈。


问答环节

面试官(张姐):那你先给我捋捋,HashMap 调用 put 方法时,底层的 putVal 是咋干活的?

malog:行!putVal 的流程大概分 “初始化→算索引→插数据→查扩容” 这几步~首先会先瞅 table 数组是不是空的,要是没初始化,就调用 resize () 整个默认长度 16 的数组;然后给 key 算 hash 值 —— 这里有个 “扰动算法”,把 key 的 hashCode 高 16 位和低 16 位异或一下,再和数组长度减 1 做位运算,算出要放的索引位置。要是这索引位置是空桶(table [i] == null),直接插新节点就行;要是非空,就分情况:要么 key 重复了直接覆盖 value,要么是红黑树节点就往树里插,要么是链表就遍历到尾巴插新节点 —— 插完还得看链表长度是不是超 8,不过光超 8 还不够,得数组长度也超 64 才会转红黑树,不然只是扩容~最后插完了要是 size 超过阈值(容量 ×0.75),就再 resize 扩容。

面试官(张姐):细节挺到位!那我追问下:那个 “扰动算法” 到底为啥要搞个高 16 位和低 16 位异或?直接用 hashCode 不行吗?

malog:还真不行!比如数组初始长度是 16,(n-1) 就是 15(二进制是 00001111),要是直接用 hashCode 和它做位运算,只有低 4 位参与计算,高 16 位的特征就浪费了,很容易撞哈希冲突。把高 16 位和低 16 位异或,相当于让高位的 “特征” 也混到低位里,散列性更好,能少点冲突~

面试官(张姐):懂了!那常有人说 “HashMap 链表长度到 8 就转红黑树”,这说法对吗?

malog:这是个常见误区!得满足两个条件:链表长度 > 8 且 数组长度 > 64。要是数组长度没到 64,就算链表长过 8,也不会转红黑树,而是触发扩容 —— 毕竟数组太小的时候树化,反而占内存,不如先扩容让数据更分散~

面试官(张姐):那 put 完之后,啥时候会触发扩容?扩容是咋扩的?

malog:当 size(实际存储的键值对数量)超过阈值(threshold = 容量 × 负载因子,默认负载因子是 0.75)的时候,就会调用 resize () 扩容。扩容是把数组容量翻倍,然后把旧数组里的节点重新计算索引,迁移到新数组里 ——Java 8 之后迁移的时候还会顺便把链表拆成两个,效率比之前高不少。

面试官(张姐):不错不错,源码细节吃得挺透!


重点问题和参考回答

序号重点问题参考回答
1HashMap 的 put 方法底层(putVal)流程是啥?分 4 步:① 检查 table 数组,未初始化则调用 resize () 初始化(默认长度 16);② 用 “扰动算法” 计算 key 的 hash 值,结合数组长度得到索引;③ 空桶直接插节点,非空则分情况(key 重复覆盖 value / 红黑树插入 / 链表尾插,满足条件则树化);④ 插入后 size 超阈值则触发 resize () 扩容。
2扰动算法(hash 方法)的作用是啥?把 key 的 hashCode 高 16 位与低 16 位异或,让高位特征参与索引计算,增强散列性,减少哈希冲突(避免仅低几位参与运算导致的冲突)。
3HashMap 链表转红黑树的条件是啥?需同时满足:① 链表长度 > 8;② 数组长度 > 64。若数组长度不足 64,链表超长会触发扩容而非树化。
4HashMap 的扩容触发条件和扩容逻辑是啥?触发条件:size(实际键值对数量)> 阈值(容量 × 负载因子 0.75);扩容逻辑:数组容量翻倍,重新计算旧节点的索引并迁移到新数组,Java 8 后会拆分链表提升效率。
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/16 7:23:43

DTIIA 4.11 导料槽

作用导料槽的作用是:引导物料 落到输送带正中间 并确保 其顺着输送方向运动。结构/组成 导料槽设计为三段式,依次为:后挡板、槽体和前帘。槽体长度有1500和2000mm两种。设计者可通过增加槽体的数量和选择不同的槽体长度获得大于1500mm&#x…

作者头像 李华
网站建设 2026/4/16 7:20:41

发那科A06B-0257-B400 伺服电机详细介绍

A06B-0257-B400 伺服电机概述A06B-0257-B400 是发那科(FANUC)公司生产的一款交流伺服电机,广泛应用于数控机床、工业机器人及自动化生产线。该电机以其高精度、高响应速度和稳定性著称,适用于需要精确位置控制和高速运动的工业场景…

作者头像 李华
网站建设 2026/4/16 9:06:18

AutoGPT项目常见报错及解决方案汇总

AutoGPT项目常见报错及解决方案汇总 在当前AI技术快速演进的背景下,我们正见证一个从“工具型助手”向“自主代理”的深刻转变。过去,用户需要一步步告诉AI“做什么”和“怎么做”,而现在,像AutoGPT这样的系统已经能够基于一个模糊…

作者头像 李华
网站建设 2026/4/15 19:58:37

3、云计算与机器学习:从基础到应用

云计算与机器学习:从基础到应用 1. 云计算概述 云计算是一种通过常见提供商(如亚马逊、谷歌和微软)按需提供高级计算设施的模式。它将强大的可扩展计算系统框架视为“云”,能按需为组织和个人用户提供全球范围的应用和服务。其核心是提供处理能力、存储和软件这三种主要服…

作者头像 李华
网站建设 2026/4/16 9:07:12

初始前端(新手中的新手)

最近跟着学校出去实践,了解也学了一些前端,随便写点总结,当做笔记也是整理思路的过程。本篇博客更像是我作为一个刚接触前端的人的自言自语,有些东西,我只是记录,并不会深入分析,因为我还没学多…

作者头像 李华
网站建设 2026/4/16 9:07:04

20、FreeBSD 系统中 USB 驱动开发详解

FreeBSD 系统中 USB 驱动开发详解 1. USB 传输机制 在 FreeBSD 系统里,USB 数据传输涉及到回调函数的执行,回调函数会在由类型、端点和方向所指定的端点进行数据传输前后被调用。其函数原型如下: typedef void (usb_callback_t)(struct usb_xfer *, usb_error_t);其中,…

作者头像 李华