当前位置: 首页 > 科技观察

为什么HashMap的负载因子是0.75?将红黑树阈值转换为8?

时间:2023-03-18 17:53:12 科技观察

文本负载因子是哈希表在其容量自动增加之前可以有多满的度量。它测量哈希表的空间使用情况。负载因子越大,哈希表的填充度越高,反之亦然。对于使用链表方法的哈希表,查找一个元素的平均时间是O(1+a)。因此,负载因子越大,空间利用得越充分,但结果是搜索效率下降;如果负载因子太小,哈希表中的数据就会过于稀疏,造成空间的严重浪费。查看源码会发现,在初始条件下,HashMap在时空之间选择了0.75/***Theloadfactorusedwhennonespecifiedinconstructor.*/staticfinalfloatDEFAULT_LOAD_FACTOR=0.75f;但为什么必须是0.75?不是0.8,0.6,这里有一个很重要的概念:泊松分布。相信大家都学过概率论,对这个著名的定律应该既熟悉又陌生。本文的重点不是给大家普及概率论的知识,这里简单介绍一下。泊松分布是最重要的离散分布之一,它常出现在X代表一定时间或空间内发生的事件数量时。举个简单的例子,如果你是老板,新开了一家酒店,这个时候应该怎么准备当天的食材呢?准备太多,最后卖不了那么多菜,只能浪费扔掉;不能接生意。但是你有很多同行和朋友会告诉你很多他们的经历。比如把一天分成几个时间段,早上、下午、晚上每个时间段来多少客人,每桌要点多少道菜。综合起来,可以大致知道一天内需要准备多少食材。看一下HashMap源码注释的原话:理想情况下,在随机hashCodes下,bins中的节点频率服从泊松分布,对于默认的resizingthreshold为0.75,参数平均为0.5左右,虽然有由于调整粒度,方差很大。忽略方差,列表大小k的预期出现次数为(exp(-0.5)*pow(0.5,k)/factorial(k))。0:0.606530661:0.303265332:0.075816333:0.012664:0.001579525:0.00015796:0.00000013167:0.00000000948:0.000000948:0.00000006多:少于1百万的情况,使用了一百万次,使用了一个理想的情况。随机哈希码,节点出现的频率按照哈希桶中的泊松分布,比较桶中元素个数和概率表。可以看出,当使用0.75作为加载因子时,当桶中的元素个数达到8时,概率已经变得很小,所以每次碰撞的位置链表长度几乎不可能超过8,所以当链表节点达到8时,开始转换成红黑树。转载本文请联系程序员大地公众号。