【简要总结】Java1.8下的HashMap

HashMap采用的是数组+链表+红黑树的形式。数组是可以扩容的,链表是可以转化为红黑树的。

用户可以设置的参数:初始总容量默认是16,默认的加载因子是0.75

容量*加载因子=阈值


什么时候扩容?

(1)当前容量超过阈值

(2)当链表中元素个数超过默认设定(8),当数组的大小还未超过64的时候,此时进行数组的扩容,如果超过则将链表转化成红黑树。


什么时候链表转化为红黑树?

当数组大小已经超过64并且链表中的元素个数超过默认设定(8)时,将链表转化为红黑树。


put过程

1.根据key计算出hash

2.hash&(数组长度-1)得到所在数组的index

3.如果该index位置的Node元素不存在,则直接创建一个新的Node

  如果该index位置的Node元素是TreeNode类型即红黑树类型了,则直接按照红黑树的插入方式进行插入

  如果该index位置的Node元素是非TreeNode类型则按照链表的形式进行插入操作,链表插入操作完成后,判断是否超过阈值TREEIFY_THRESHOLD(默认是8),超过则要么数组扩容,要么链表转为红黑树

4.判断当前总容量是否超过阈值,如果超出则执行扩容


扩容过程

按照2倍扩容的方式,那么就需要将之前的所有元素重新按照2倍桶的长度重新计算所在桶。这里为啥是2呢?

因为2倍的话,更加容易计算出它们所在的桶,并且各自不会互相干扰。如:原桶数组长度是4,现在桶数组长度是8,那么,原桶0中的元素会被分到新的桶0和桶4里面,原桶1中的元素会被分到新的桶15里面,原桶2中的元素会被分到新的桶2和桶6里面,原桶3中的元素会被分到新的桶3和桶7里面。为什么是这样呢?

0中的元素的hash值后2位必然是00,这些hash值可以根据后3000或者100分成2类数据。它们分别&(8-1),即&111,则后3位为000的在桶0中,后3位为100的必然在桶4中。其他同理,也就是说,桶4和桶0重新瓜分了原来的桶0中的元素。

如果换成其他倍数,那么瓜分地就比较混乱。

这样在瓜分数据时,只需要先把这些数据分类,如上述桶0中分成000100这两类,然后,直接构成新的链表,分类完成后,直接将新的链表挂在对应的桶下面即可。


get过程

1.根据key计算出hash

2.hash&(数组长度-1)得到所在数组的index

3.如果要找的key就是上述数组index位置的元素,直接返回该元素的值

  如果该数组index位置的元素是TreeNode类型,则按照红黑树的查询方式进行查找

  如果该数组index位置的元素是非TreeNode类型,则按照链表的方式进行遍历查找

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值