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

相关推荐
Yaml440 分钟前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~42 分钟前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong16168843 分钟前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
wheeldown44 分钟前
【数据结构】选择排序
数据结构·算法·排序算法
aloha_7891 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
记录成长java2 小时前
ServletContext,Cookie,HttpSession的使用
java·开发语言·servlet
睡觉谁叫~~~2 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
程序媛小果2 小时前
基于java+SpringBoot+Vue的旅游管理系统设计与实现
java·vue.js·spring boot
小屁孩大帅-杨一凡3 小时前
java后端请求想接收多个对象入参的数据
java·开发语言
java1234_小锋3 小时前
使用 RabbitMQ 有什么好处?
java·开发语言