社招必备!HashMap 的 put 方法底层揭秘,面试官都说赞!

B站影视 2024-12-28 09:16 3

摘要:Hello 大家好!我是小米,一个积极分享技术的小伙伴,今天我们继续聊聊 Java 面试中的热门话题——HashMap 的 put 方法的具体流程。这是一个老生常谈的面试题,但很多人了解得不够深入,导致在面试时只能泛泛而谈。今天我们通过一个生动的小故事,来剖析

Hello 大家好!我是小米,一个积极分享技术的小伙伴,今天我们继续聊聊 Java 面试中的热门话题——HashMap 的 put 方法的具体流程。这是一个老生常谈的面试题,但很多人了解得不够深入,导致在面试时只能泛泛而谈。今天我们通过一个生动的小故事,来剖析一下它的底层原理,希望大家看完后能对它了然于心!

在一个神秘的「Java 集合世界」中,有一座巨大的宫殿,这就是 HashMap。它负责存储和管理这个世界中的各种「钥匙-宝藏(key-value)」对。

一天,一个叫作「put 方法」的小勇士接到了任务:把一件新的「钥匙-宝藏」对送进 HashMap 的宫殿。

第一步:勇士探路——检查钥匙的合法性

put 方法的小勇士,首先检查了任务交给他的钥匙(key)。他要确保钥匙不能是 null,否则会很麻烦。不过,hashMap 的设计师考虑周到,允许存储一个特殊的 null 键,并将它放在宫殿的「入口大厅」(bucket[0])。

代码片段:

第二步:钥匙定位——计算哈希值

接着,小勇士需要找到钥匙在宫殿中的具体位置。他通过钥匙的 hashCode 方法,计算出一个哈希值(hash value)。不过,为了避免直接使用 hashCode 导致的分布不均,他会对哈希值进行一番加工。

代码片段:

这个加工方法通常是对 hash 值进行高位运算,以增强分布随机性。具体实现如下:

第三步:选择房间——定位到桶(bucket)

计算出哈希值后,小勇士根据宫殿的总房间数(即数组容量)找到对应的房间(bucket)。这个过程是通过对数组长度取模来完成的。

代码片段:

第四步:探查房间——查找链表或树结构

找到房间后,小勇士进入房间查看。房间可能是空的,也可能存放着一堆钥匙-宝藏对。为了确保钥匙的唯一性,他会在房间中查找是否已经存在相同的钥匙。

如果房间里是链表结构,小勇士会遍历每一个节点,比较 key.equals。如果房间里是红黑树,小勇士会用树的查找规则寻找相应节点。

代码片段:

HashMap 的宫殿设计师不仅考虑到了普通情况下的性能,还特别设计了一项优化:当房间里的链表节点数量超过阈值(默认是 8)时,链表会升级为红黑树。这大大提升了在大量数据下的查找效率。

代码片段:

如果房间里没有相同的钥匙,小勇士会在房间里新增一个节点来存储新的钥匙-宝藏对。

代码片段:

这里的 Node 是 HashMap 的一个静态内部类,它封装了 key、value 以及指向下一个节点的指针(用于形成链表)。

任务完成后,小勇士还有一个重要的责任——检查宫殿是否需要扩建。如果宫殿的负载因子(load factor)超过阈值(默认是 0.75),他就会触发扩容操作。

扩容的过程很有趣,它会创建一个新的宫殿,容量是当前的两倍,然后重新分配所有钥匙-宝藏对的位置。

代码片段:

完整流程总结

从钥匙检查到定位再到存储,put 方法的工作流程可以总结为以下几步:

检查 key 是否为 null。计算 hash 值并定位桶。遍历桶中的链表或树结构,检查是否有相同的 key。如果有相同的 key,则更新对应的 value;否则,创建新的节点插入。检查负载因子,必要时进行扩容。

当面试官问到「HashMap 的 put 方法的具体流程」时,可以从以下几个方面展开:

大体流程:概述 put 方法的整体逻辑。细节补充:强调 hash 值计算、链表到红黑树的转换、扩容等核心细节。性能优化:分析 HashMap 的时间复杂度(插入、查询的均摊复杂度是 O(1))以及在极端情况下可能退化为 O(n) 的原因。

HashMap 的设计精妙且高效,理解它的底层实现不仅对面试有帮助,也能帮助我们写出更高效的代码。希望今天的小故事能让大家对 put 方法有更深刻的认识!

如果你觉得这篇文章对你有帮助,记得点个「在看」或者分享给你的朋友!如果还有其他想了解的话题,欢迎留言告诉我!我们下期再见啦~

来源:灿轩教育

相关推荐