一起探讨hashmap底层实现原理以及如何解决hash冲突——小布

302 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第21天,点击查看活动详情

对你这份喜欢最后还是止于心酸.jpg

hashmap:

hashmap实现了map接口,map接口是对键值对的一个映射,map中不允许出现重复的key,但是key和value都可以为空,而且hashmap线程不安全。因为它是非synbchronized的,都是collection集合的方法可以保证synchronized,所以hashmap也是可以被保证synchronized,多个线程访问它的时候,只能有一个线程更改map。

hash冲突:

就是我们根据不同的key计算的哈希值相同,也就是我们根据他的索引找到具体地址,发现已经有值了,就会发生冲突。

解决办法:

1、连地址法:就是把hashmap的实现,我们知道索引位置,去形成链表,做尾插操作,超过8就变成红黑树

2、再哈希法:就是再次去构造哈希函数,计算出不同的哈希值,这样就不会产生冲突了。

3、建立公共溢出区:把哈希表分成公共表和溢出表, 当发生溢出时,就把溢出数据放到溢出表中。

hashmap底层实现原理:

首先hashmap它是一个entry对象组成的数组,entry对象又是key,vlaue形式的键值对,我们可以根据Key去用hashcode()去计算相应的哈希值,再通过哈希值去计算它在数组中的索引,找到索引,如果是null,就是直接插入,如果不为空,就做循环遍历,找到相同哈希值的对象,然后对比key,如果哈希值相同,key相同,就是把vlaue进行覆盖,如果key不同,就把这个对象进行链表尾插,长度超过8就变成红黑树。

在hashMap中放入(put)元素,有以下重要步骤:

1、计算key的hash值,算出元素在底层数组中的下标位置。

2、通过下标位置定位到底层数组里的元素(也有可能是链表也有可能是树)。

3、取到元素,判断放入元素的key是否==或equals当前位置的key,成立则替换value值,返回旧值。

4、如果是树,循环树中的节点,判断放入元素的key是否==或equals节点的key,成立则替换树里的value,并返回旧值,不成立就添加到树里。

5、否则就顺着元素的链表结构循环节点,判断放入元素的key是否==或equals节点的key,成立则替换链表里value,并返回旧值,找不到就添加到链表的最后。

精简一下,判断放入HashMap中的元素要不要替换当前节点的元素,key满足以下两个条件即可替换:

1、hash值相等。

2、==或equals的结果为true。