HashMap的实现原理(下)

前言:基于上篇《HashMap的实现原理(上)》,我们学会了什么是HashMap、为什么需要HashMap,以及HashMap的基本实现原理。即回答了三个问题:“What? Why? How? ”。 这篇,将继续讲解,什么是Hash冲突,为什么会出现Hash冲突和其解决方法。但在讲解的流程上,我们先解释Why,再进而得出What,最后再讲解How。

一、为什么会出现Hash冲突?(Why)

由上篇《HashMap的实现原理(上)》中的第三节部分得知,HashMap会通过hash算法来计算,某一条数据,应该存储在数组的某一个位置上,即通过hash算法来获取数组的下标。

在最优最好的情况下,不同的数据,通过一定的hash算法计算,总是能得出不同的下标。但是,我们无法避免会出现这样的情况:不同的数据,得出相同的下标,这也就是我们经常所说的,Hash冲突(What)

二、如何解决Hash冲突?(How)

实际上,Hash并不是单一的数组结构,而是数组加链表的结构,即:

[链表0][链表1].... ...[链表n]

每一个数组的元素,都装有一个链表,就像一个桶一样,装了一层层的东西。所以,管每一个数组元素叫bucket,而不是element。当出现hash冲突的时候,冲突的数据,以链表的形式拼接起来。即:

{} 代表链表的节点,每一个节点,至少包括:hash、key、value。
[链表0] =》 内部 =》
{hash=0,key="test", value=1} ---下个节点--->{hash=0,key="abc", value=2}

由上面的代码可知,虽然key不一样,一个是test, 一个是abc。但基于不同的hash算法,有可能会计算出相同的hash值0。这样,这两个元素就是冲突的,但通过链表,把它们链表起来,都存放在数组下标为0的位置,就解决了这个冲突的问题。

**但是,基于链表查找的劣势,当链表的某一个节点,即某一只桶里面存的节点越多时,跟HashMap查找相关功能的效率,就会越慢。**所以,hash算法越好,出现冲突的概率就越低。

总结: 到此为止,我们已经学会了为什么会出现Hash冲突,以及如何解决Hash冲突。但这里面有两个点,需要你们自己深入去了解下,如果有兴趣的话:

1、Hash算法。
2、 HashMap源码里面final Node<K,V> getNode(int hash, Object key)方法的实现。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值