HashSet为什么链表长度超过8会发生扩容

前言

续接前文:HashSet的底层扩容原理,在文章末尾留下了一个疑问,为什么当HashSet的链表长度超过8就会扩容?
浅谈HashSet与HashMap的底层扩容原理
现已解决啦~


直接带大家上源码

在这里插入图片描述

解析源码

在HashMap的源码中,可以看到这一段描述,它的大概意思呢就是说,在底层结构中,树的大小是常规链表大小的两倍,非必要情况下,是不会用树结构的。就算因为某些原因用了树结构,也会在它变小时(删除、调整大小),会从树结构转变回普通的链表。

源码注释中还提到了在随机的哈希码下,链表的每个节点的命中率服从泊松分布。

什么是泊松分布呢,就是数学中一个很牛逼的统计学的知识,通常用于描述单位时间(或空间)内随机事件发生的次数。

从源码注释中还可以看到大佬给我们罗列出来的8个概率:因为HashSet底层原理和HashMap一样,都是数组+链表+红黑树结构,当数组中没有元素,也就是链表长度为0时,jvm往这个位置添加元素的概率是0.6。

如果当前数组中有元素,并且新元素与旧元素发生哈希碰撞,equals又不相等的情况下,就会添加到旧元素下方(本文都以jdk8以后为例),此时的概率为0.3。以此类推,当同一条链表添加到第8个元素的概率都不足千万分之1了。这个概率跟买彩票中一等奖的概率差不多。

如果真的有极端情况,底层就会认为,是不是你这个数组太小了,所以这么小的概率都发生了,于是就自动扩容了。因为随着数组的扩容,原先所有的链表都会打散,重新分配到各个数组中。

前文我们还提到,链表长度不止8是阈值,9也是阈值。是因为我们重写了hashcode的方法,使得返回值永远都是一样的,不管打乱几次,还是会被重新分配到同一条链表上。

而当数组扩容到64时,就会触发转换红黑树的条件,此时的HashSet底层就是红黑树了。


总结

当链表长度超过8时,不论数组中有无元素,不论总个数是否达到阈值,都会直接扩容!直到整个数组容量达到64并且链表长度大于8时,HashSet底层由数组+链表转变为红黑树才会停止。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值