为什么 HashMap 默认负载因子是0.75?

1、典型回答

负载因子 (Load Factor)也叫扩容因子,它是一个用于控制 HashMap 何时进行扩容的参数。当 HashMap 中存储的键值对数量,超过了 HashMap 总容量乘以扩容因子时,HashMap 就会进行扩容操作。

例如 HashMap 的总容量为 16,扩容因子为 0.75,那么当 HashMap 中存储的键值对大于 12 (16*0.75)时HashMap 就会进行扩容。

注:负载因子的值是 0 到 1 之间 (大于 0,小于 1)。

为什么负载因子是 0.75?

对于这个问题,官方给的答案是这样的:

As a general rule, the default load factor (.75) offers a good tradeoff between time and space costs. Highervalues decrease the space overhead but increase the lookup cost reflected in most of the operations of theHashMap class, including get and put). The expected number of entries in the map and its load factor shouldbe taken into account when setting its initial capacity, so as to minimize the number of rehash operations. Ifthe initial capacity is greater than the maximum number of entries divided by the load factor, no rehashoperations will ever occur.

上面的意思大概来说就是,负载因子为 0.75 是一种经验性的权衡,这个值被认为是在时间和空间效率之间找到一个良好平衡。

  • 当负载因子比较大的时候,那么扩容就会比较晚,空间利用率就会比较高,但发生哈希冲突的概率就会增大那么插入的时间就会变长;
  • 当负载因子比较小的时候,那么扩容会比较早,发生哈希冲突的概率会变小,插入的时间会变快,但空间利用率就会很低。

因此选择 0.75 是空间和时间效率的一种平衡

2、全面剖析

负载因子(Load Factor) 也叫扩容因子,它是一个用于控制 HashMap 何时进行扩容的参数。负载因子的计算公式为:负载因子 = 元素数量/哈希表容量。

使用 0.75 的负载因子是空间 (内存占用率) 和时间 (添加元素的时间)的一种平衡。

因为内存利用率越高,发生哈希冲突的概率越大,发生哈希冲突的概率越大,那么添加元素的性能越低,而当内存利用率越低时,发生哈希冲突的概率越小,添加元素的性能就越高,所以此时就需要使用负载因子,来平衡二者之间的关系。

3、知识扩展

0.75 的科学推断

官方并未对负载因子为 0.75 做过明确的解释,只是大概的说了一下,0.75 是空间和时间复杂度的平衡,但更多的细节是未做说明的,然而 Stack Overflow 一位大神从科学的角度推测了这个问题的答案,链接如下:

https://stackoverflow.com/questions/10901752/what-is-the-significance-of-load-factor-in-hashmap

简单翻译一下,它是通过二项式哈希函数的冲突概率来解释 0.75 这个问题的。假设一个哈希桶为空和非空的概率为 0.5,我们用 s 表示容量,n 表示已添加元素个数,根据二项式定理,桶为空的概率为:

P(0) = C(n,0)*(1/s)^0 *(1 - 1/s)(n - 0)

因此,如果桶中元素个数小于以下数值,则桶可能是空的公式为:

log(2)/log(s/(s - 1))

也就是说,当 趋于无穷大时,如果增加的键的数量是 P(0) = 0.5,那么 n/s 很快趋近于 g(2),而 g(2)0.693。所以,合理值大概在 0.7 左右,这就是对负载因子为 0.75 的一个科学推测。

相关推荐
寻道码路17 分钟前
LangChain4j Java AI 应用开发实战(四):提示词工程进阶 - 模板化与结构化 Prompt 设计
java·人工智能·ai·prompt·aigc
lcreek6 小时前
Java 反序列化漏洞深度解析(一):从URLDNS到真正的DNS探测
java·反序列化漏洞
Raink老师6 小时前
【AI面试临阵磨枪-70】Agent 系统如何做分布式调度、跨服务协作、故障恢复?
人工智能·面试·职场和发展
杰克尼6 小时前
天机学堂复习总结(day03-day04)
java·开发语言·redis·elasticsearch·spring cloud
Raink老师6 小时前
【AI面试临阵磨枪-71】如何用 AI 优化推荐系统、内容审核、广告创意、搜索体验?
人工智能·面试·职场和发展
x***r1516 小时前
jdk-11.0.16.1_windows使用步骤详解(附JDK 11环境变量配置与验证教程)
java·开发语言·windows
Raink老师6 小时前
【AI面试临阵磨枪-72】电商全场景 AI Agent 设计(商品咨询 / 订单 / 物流 / 售后 / 退款)
人工智能·面试·职场和发展
弹简特7 小时前
【Java项目-轻聊】01-项目演示+项目介绍+准备工作+项目源码
java
tongluowan0077 小时前
jvm垃圾回收器 - CMS-已弃用的垃圾回收器
jvm·cms·垃圾回收器
luck_bor7 小时前
File类&递归作业
java·开发语言