为什么 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 的一个科学推测。

相关推荐
毕设源码-钟学长11 分钟前
【开题答辩全过程】以 浮生馆汉服租赁管理系统为例,包含答辩的问题和答案
android·java·tomcat
90后小陈老师11 分钟前
用户管理系统 07 项目前端初始化 | 新手实战 | 期末实训 | Java+SpringBoot+Vue
java·前端·spring boot
Coder-coco23 分钟前
点餐|智能点餐系统|基于java+ Springboot的动端的点餐系统小程序(源码+数据库+文档)
java·vue.js·spring boot·小程序·论文·毕设·电子点餐系统
Halo_tjn24 分钟前
Set集合专项实验
java·开发语言·前端·python
司铭鸿42 分钟前
图论中的协同寻径:如何找到最小带权子图实现双源共达?
linux·前端·数据结构·数据库·算法·图论
嘟嘟w1 小时前
Spring 核心注解深度分析
java·后端·spring
9***Y481 小时前
Java开发工具IntelliJ IDEA技巧
java·开发语言·intellij-idea
Java爱好狂.1 小时前
2025全年Java面试真题总结!
java·jvm·高并发·多线程·java面试·后端开发·java八股文
Charles_go2 小时前
C#中级39、什么是依赖注入设计模式
java·设计模式·c#
ComplexPy2 小时前
ZKMall-B2B2C Redission延时队列
java·redis