HashMap的底层实现原理

你了解HashMap的底层实现原理吗?

HashMap的底层是Hash表结构,元素的排列是根据哈希算法和哈希函数排序的,且不可重复。

JDK8以前,Hash表的底层是【数组】+【链表】

JDK8及之后,变成了【数组】+【链表】+【红黑树】

存入新键值对时,如果出现哈希冲突,会先判断键是否相同,如果键相同,会比较值,值相同则不放入,值不同则修改原值;如果键不相同,则会以链表形式挂下来,并且1.7版本中是头插法,1.8版本是尾插法。

什么是哈希冲突?

哈希冲突就是两个元素在通过哈希函数后,得到的角标是相同的,在同一个哈希槽中。哈希冲突的四种解决思路分别是:重哈希法,开放地址法,建立公共溢出,链地址法。

HashMap的扩容机制是怎么样的?它什么时候会转化为红黑树?

Hash表中数组的分手手动初始化,和自动初始化,自动初初始会在第一次插入元素时开辟空间,默认长度为16,扩容因子为0.75,每次扩容量为自身的2倍长度,扩容之后存入数组的新索引位置就会改变。手动初始化的话,可以在创建对象时自定义初始数组长度,但HashMap不一定会自主设置的数值初始化数组,而按2的n次方创建。

HashMap1.7版本的的扩容时机是先判断是否达到阈值,达到先扩容,再添加元素,并且采用的是头插法,也就是旧元素挂在新元素下。

而HashMap1.8的扩容时机是先添加元素是否达到阈值,达到直接扩容,且使用的是尾插法,即新元素挂在旧元素下面。

初始化后,当存入新的键值对时,会先判断数组长度是否大于64,再判断链表元素是否大于等于8时,如果两者都成立,链表会自动转换成红黑树,如果数组小于64,会从第9个开始先扩容,直到数组大于等于64时,链表长度再增加,就会转为红黑树。

细节:

在添加第一个元素的时候是直接添加进数组的,而不会进入到红黑树转化的判断的,所以里面的binCount并没有创建。添加第二元素并发生了哈希冲突时,才进入红黑树转化的判断,同时初始化binCount=0,它判断的是binCount>=7,也就是0至7,有8个元素时,再加上没有进行判断的1个元素,即第9个元素时,才会转化为红黑树。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值