面试题:HashMap 是怎么解决哈希冲突的?

开发 前端
现在的企业级开发中HashMap几乎是最常用到的容器,了解HashMap 是怎么解决哈希冲突的,有助于我们开发出更加优秀的代码。那么这个问题就是面试官想考察我们是不是平日里善于积累,仔细思考这方面的知识!

前言

       今天来分享一道比较好的面试题,“HashMap 是怎么解决哈希冲突的?”对于这个问题,我们一起看看考察点和比较好的回答吧!

考察点

      现在的企业级开发中HashMap几乎是最常用到的容器,了解HashMap 是怎么解决哈希冲突的,有助于我们开发出更加优秀的代码。那么这个问题就是面试官想考察我们是不是平日里善于积累,仔细思考这方面的知识!

回答  

关于这个问题,我从三个方面来回答:

1.hash冲突的基础就是hash算法和hash表这种数据结构。先讲讲hash算法和hash表。

①Hash 算法,就是通过散列算法,把任意长度的输入变成固定长度的输出。这个输出就是散列值。

hashValue1  = hash(inputStr1);
hashValue2  = hash(inputStr2);
hashValue1和hashValue2的长度一样

②Hash 表又叫做“散列表”,其本质是通过key,可以直接访问在内存存储位置的数据结构。因此在表现上,我们可以通过hash函数把key映射到散列表中的某个位置,进而获取这个位置的数据,这样能够加快查找速度。

③那么我们所说的hash 冲突,因为哈希算法计算的数据是无穷的,而计算的结果范围是有限的,这样就会造成不同的输入得到的结果确实一样的情况。也就是说发生了冲突。如图所示:

2.如何结果hash冲突呢?这里讲一下常用的4中方法。

①开放定址法,也被称为线性探测法,其原理是这样的,从发生冲突的那个位置开始,通过一定的次序从hash表里面找一个空闲的位置。之后将发生冲突的元素存入到这个空闲位置中。在应用上面,我们常见的ThreadLocal就是用到了线性探测法来解决hash冲突。如图,在 hash 表索引 1 的位置存了一个 key=name,当再次添加key=hobby 时hash 计算得到的索引也是 1,这个就是 hash 冲突。而开放定址法,就是按顺序向前找到一个空闲的位置来存储冲突的 key。

②链式寻址法,这是一种非常常见的方法,简单理解就是把存在 hash 冲突的 key,以单向链表的方式来存储,比如 HashMap 就是采用链式寻址法来实现的。向这样一种情况(如图),存在冲突的 key 直接以单向链表的方式进行存储。

③再 hash 法,就是当通过某个 hash 函数计算的 key 存在冲突时,再用另外一个 hash 函数对这个 key 做 hash,一直运算直到不再产生冲突。这种方式会增加计算时间,性能影响较大。

④. 建立公共溢出区, 就是把 hash 表分为基本表和溢出表两个部分,凡是存在冲突的元素,一律放入到溢出表中。

3.HashMap 在 JDK1.8 版本中,通过链式寻址法+红黑树的方式来解决 hash 冲突问题,其中红黑树是为了优化 Hash 表链表过长导致时间复杂度增加的问题。当链表长度大于 8 并且 hash 表的容量大于 64 的时候,再向链表中添加元素就会触发转化。

以上就是我对于这个问题的理解。

本文转载自微信公众号「程序员的故事」,可以通过以下二维码关注。转载本文请联系程序员的故事公众号。程序员的故事原创文章,遵循CC 4.0 BY-SA版权协议。

责任编辑:武晓燕 来源: 程序员的故事
相关推荐

2022-08-29 07:31:48

HashMap线程扩容

2023-02-17 14:35:15

HashMapNode类型

2015-09-07 09:15:54

Java面试题HashMap

2020-06-04 14:40:40

面试题Vue前端

2014-09-19 11:17:48

面试题

2021-03-12 13:57:13

零拷贝技术

2023-07-05 07:30:44

StringHashMapKey类型

2023-07-28 08:04:56

StringHeaatomic线程

2023-11-13 07:37:36

JS面试题线程

2011-03-24 13:27:37

SQL

2021-08-06 09:27:07

HashMap数据结构

2009-08-11 10:12:07

C#算法

2009-06-06 18:36:02

java面试题

2009-06-06 18:34:05

java面试题

2015-09-02 09:32:56

java线程面试

2023-05-19 08:21:40

MarginCSS

2024-08-09 11:52:18

2020-09-21 11:10:06

Docker运维面试

2010-11-26 10:53:29

戴尔

2014-07-15 11:10:01

面试题面试
点赞
收藏

51CTO技术栈公众号