数据结构论坛

首页 » 分类 » 分类 » HashMap的底层原理及相关面试题整理
TUhjnbcbe - 2023/7/5 20:14:00

概述

在Java基础知识的面试中,HashMap绝对占据很重要的一席之地。本文对常见的面试题进行一个整理,同时,对相关原理进行适当深度的探讨。

HashMap有哪些特性?

HashMap有哪些特性?或者说为什么要使用HashMap?

重点就是快。

进行键值对的快速存取。允许为null。key值重复则覆盖。线程不安全。无序。HashMap为什么快?

HashMap为什么快?它的底层原理是什么?

首先从数据结构上来说,它是一个数组,数组中的元素是链表,或者红黑树。

HashMap数据结构

在数组中找一个元素,只需要知道该元素所在位置的下标,根据数据的起始位置和偏移量,即可快速定位到元素。

HashMap快的原因就在这里。在存放的时候,就基于特定的规则,把元素放到可预期的位置,这样,就提高了读取的速度。打个比方:一堆球,编号1到,在存放的时候,如果都放到一个筐里,当要求取出指定编号的球时,在最坏的情况下,就需要找次。但是,如果按照单双数,分别放到两个筐里,那么,在取出时,最坏情况下,也只需要50次。

在写的时候,加入额外的动作,提供额外的空间(多用了个筐),就达到了提升读取速度的效果。

这里,有面试官会问什么是红黑树?

这个问题就基本上不在HashMap范围内了。可以简单描述下,面试官如追问,再详细作答。如下:

红黑树是一个平衡二叉树,通过特定的规则,保持二叉树的平衡。链表的查询复杂度是n,平衡二叉树的查询复杂度是logn。

HashMap在写或读时,如果计算下标?

写时,会写入一个键值对,读时,会基于键,读出值。HashMap通过某种计算,把键换算成了数组的下标。

换算过程分两步:

计算key的hashcode值。将hashcode值,无符号右移16位,再与原值做异或运算。源码如下:

hash算法源码

为什么不用更通俗易懂的过程?比如说直接用hashcode值除以数组长度,取余数作为下标?

原因有二:

快。每次读写都要做这个运算。它自然是真快越好。对于计算机来说,位运算的效率显然要更高些。均匀。要尽可能的保证均匀,即尽可能的让元素均匀的落在数组中的每个位置上。假设所有元素都落在了同一个位置上,那每次读的效率就等同于读链表或者读树了。简述向HashMap中put元素的过程?

向HashMap中put一个键值对,键为key,值为value。过程如下:

通过Key计算出下标。将value存放到下标所指的位置。存放时,分几种情况:

如所指位置为空,直接放入元素。如所指位置已有元素,即发生了Hash碰撞,则判断已有元素的数量,调用插入链表或插入树的方法。jdk1.7之前都是链表,jdk1.8之后,元素数量大于8时,会构建成树。

插入时,判断key是否相同,key相同时,会覆盖原有元素。

插入时,如HashMap中元素的数量超过阈值,会进行再散列。

为什么会发生Hash碰撞?

这个问题很简单,键经过hash算法,转换成hashCode。任何元素都可以做键。所以,键是无限的,而哈希code是int类型,int类型的数值是有限的。无限转换到有限,必然会有重复,即Hash碰撞。

前面也提到,一个好的hash算法,要求即要快,又要尽可能的使得到的下标均匀,即尽量避免Hash碰撞。

什么是再散列?

HashMap的底层首先是一个数组,那么,它就有一个长度。当存放的元素越多时,就越容易发生Hash碰撞,即HashMap“太挤了”,这个时候,我们就需要进行某个动作,使HashMap不那么挤。这个动作,就是再散列。

在put时,会判断元素的数量。如果元素数量达到或超过数组长度和负载因子的乘积,即执行再散列。过程如下:

扩容。找一块新的内存空间。长度为原数组长度的两倍。迁移。把原数组中的元素复制到新数组。由于数组长度已经发生了变化。则相应的,元素的位置也要发生改变。即要重新调用Hash算法,以计算它们的新位置。负载因子为什么是0.75而不是1?

负载因子并不是固定的,可以在构造时指定。

负载因子越大,当元素足够多时,越容易发生碰撞,读写速度会越慢。

负载因子越小,可以尽量保证了读写速度,但是再散列的过程会增多。

所以,0.75其实是基于经验总结得出的结果,取了一个平衡值。

简述从HashMap中get的过程?

基于键,从HashMap中取得Value,过程如下:

基于键,通过Hash算法得到下标。找到对应位置。如位置中为链表或者树,则进行遍历。得到目标元素,返回。复制的过程在put时已经做了,所以get相对简单。

结语

上述就是关于HashMap的一些常见的面试题。当然,除此之外,还有更多的问法,或者其它更多的问题。我们后续再进行讨论。

1
查看完整版本: HashMap的底层原理及相关面试题整理