HashMap 扩容 加载因子
HashMap 扩容 加载因子
最近在看HashMap源码,对于扩容因子=0.75感到很费解,为什么在用了75%的容量的时候就要进行扩容呢?数组中明明还有25%的空间没有使用。为什么不等到数组几乎满了(扩容因子=0.95)的时候才进行扩容?扩容因子=0.95和扩容因子=0.75有什么区别吗?
首先来看一下什么是扩容因子。假设hash函数是理想的,数据会通过hash函数均匀的映射到数组上。一个数据映射到每一个桶(bucket)的概率是相等的。那么在任意的数组容量下,put一个数据发生碰撞的概率=数组中元素的个数数组容量 \frac{数组中元素的个数}{数组容量}
数组容量
数组中元素的个数
而数组的扩容门槛threshold = capacity * loadFactorloadFactor。也就是说扩容因子就是HashMap在扩容门槛的状态下,put操作发生碰撞的概率。
那么,扩容因子等于0.75还是0.95的区别就很明显了。扩容因子=0.75。当使用量接近数组容量的75%的时候,数组中还有25%的剩余空间。平均来看,就是每4个桶(bucket)中还有一个是空的,当我们向map中put数据的时候,发生碰撞的概率是75%。因为这25%的空闲空间的存在,发生hash碰撞的概率还处在一个可以接受的范围内。
而当扩容因子=0.95的时候,平均来看,就是每20个桶(bucket)中才有一个是空的,此时数组中几乎没有空闲的桶(bucket),当我们put数据的时候,碰撞的概率是95%,几乎可以认为会发生碰撞。
除此之外,碰撞的概率越大,put的元素就越多,平均到每个桶中的元素的数量也越多。一旦发生碰撞,需要付出更大的代价。所以,如果扩容因子越大,碰撞的概率也就越大,发生碰撞后的代价也更大,结果导致效率大打折扣。
因此扩容因子=0.75也是一个空间换时间的考虑,0.75这个数值应该是经过充分的考虑决定的。
public HashMap(int initialCapacity, float loadFactor) {//初始容量不能<0if (initialCapacity < 0)throw new IllegalArgumentException("Illegal initial capacity: "+ initialCapacity);//初始容量不能 > 最大容量值,HashMap的最大容量值为2^30if (initialCapacity > MAXIMUM_CAPACITY)initialCapacity = MAXIMUM_CAPACITY;//负载因子不能 < 0if (loadFactor <= 0 || Float.isNaN(loadFactor))throw new IllegalArgumentException("Illegal load factor: "+ loadFactor);// 计算出大于 initialCapacity 的最小的 2 的 n 次方值。int capacity = 1;while (capacity < initialCapacity)capacity <<= 1;this.loadFactor = loadFactor;//设置HashMap的容量极限,当HashMap的容量达到该极限时就会进行扩容操作threshold = (int) (capacity * loadFactor);//初始化table数组table = new Entry[capacity];init();
}
在这里提到了两个参数:初始容量
,加载因子
。
这两个参数是影响HashMap性能的重要参数,其中容量表示哈希表中桶的数量,初始容量是创建哈希表时的容量,
加载因子是哈希表在其容量自动增加之前可以达到多满的一种尺度,它衡量的是一个散列表的空间的使用程度,负载因子越大表示散列表的装填程度越高,反之愈小。
对于使用链表法的散列表来说,查找一个元素的平均时间是O(1+a),因此如果负载因子越大,对空间的利用更充分,然而后果是查找效率的降低;
**如果负载因子太小,那么散列表的数据将过于稀疏,对空间造成严重浪费。**系统默认负载因子为0.75,一般情况下我们是无需修改的。
## 欢迎交流
HashMap 扩容 加载因子相关推荐
- 为什么 HashMap 的加载因子是0.75?
点击上方蓝色"程序猿DD",选择"设为星标" 回复"资源"获取独家整理的学习资料! 来源 | https://blog.csdn.net/N ...
- eui加载时间长_面试官:为什么 HashMap 的加载因子是0.75?
有很多东西之前在学的时候没怎么注意,笔者也是在重温HashMap的时候发现有很多可以去细究的问题,最终是会回归于数学的,如HashMap的加载因子为什么是0.75? 本文主要对以下内容进行介绍: 为什 ...
- 面试官:为什么 HashMap 的加载因子是0.75?
点击上方"朱小厮的博客",选择"设为星标" 后台回复"加群",加入新技术 来源:8rr.co/8V9Q 有很多东西之前在学的时候没怎么注意, ...
- 【java】为什么 HashMap 的加载因子是0.75?
1.概述 转载:为什么 HashMap 的加载因子是0.75? 有很多东西之前在学的时候没怎么注意,笔者也是在重温HashMap的时候发现有很多可以去细究的问题,最终是会回归于数学的,如HashMap ...
- 为什么 HashMap 默认加载因子非得是0.75?
点击上方 "编程技术圈"关注, 星标或置顶一起成长 后台回复"大礼包"有惊喜礼包! 每日英文 Sometimes,God does not give you w ...
- [转]为什么Java中的HashMap默认加载因子是0.75
前几天在一个群里看到有人讨论hashmap中的加载因子为什么是默认0.75. HashMap源码中的加载因子 static final float DEFAULT_LOAD_FACTOR = 0.75 ...
- HashMap与加载因子/负载因子loadFactor关系
HashMap以<key,value>的方式存放数据,存储在数组中.通过开散列方法解决冲突,数组中存放的Entry作为单向链表的表头. Entry的源码如下: static class E ...
- java中的加载因子_java - HashMap中加载因子的意义是什么?
如果水桶太满,那么我们必须仔细检查 一个很长的链表. 这就是打败这一点. 所以这是一个我有四个桶的例子. 到目前为止,我的HashSet中有大象和獾. 这是一个非常好的情况,对吗? 每个元素都有零个或 ...
- 为什么 HashMap 加载因子一定是0.75?而不是0.8,0.6?
点击上方"方志朋",选择"设为星标" 回复"666"获取新整理的面试文章 有很多东西之前在学的时候没怎么注意,笔者也是在重温HashMap的 ...
最新文章
- Redis数据库搭建主从同步(主从概念、主从配置、主从数据操作)
- (转)VS2005 SP1发布,解决只能创建WebSite,无法创建Web Application项目的问题
- golang计算单个协程占用内存
- cs231n 学习笔记(5)——神经网络part1:建立神经网络架构
- 【Linux】查询 OS、CPU、内存、硬盘信息
- Hadoop整理四(Hadoop分布式计算框架MapReduce)
- 一步一步教你安装并登陆My SQL(最详细教程,没有之一)
- [原]终于有新机器用了Intel E6500K+4G+23.6’液晶
- 设计模式(九)——代理模式(Proxy)
- android转发短信到邮箱,Android手机使用Tasker转发短信及来电
- 【机器学习】阿里云天池竞赛——工业蒸汽量预测(1)
- 【前端】JavaScript-节点操作
- 12333提交显示服务器异常,掌上12333显示没有收到异地协助认证书什么原因_具体解决办法流程_3DM手游...
- Maix Bit、K210超详细资料【保姆级教程】【学习与上手Maix Bit这一篇文章就够啦】
- 课时23:递归:这帮小兔崽子
- basler 相机取图超时_Basler|基于OpenCV的Basler相机采集图像程序
- 【GlobalMapper精品教程】031:Globalmapper在航测内业数据处理中的应用举例
- 爬虫实战-用beautifulsoup提取丁香园论坛的回复内容
- 汉王文本王OCR识别注意事项
- 递归实现钢条切割问题(Java版)
热门文章
- php 查看文件信息,文件信息查看
- 鹅厂流出两份Android Framework技术宝典火了,完整版 PDF 限时开放下载
- Proteus8.15(集电路仿真、PCB设计件和虚拟模型仿真于一体)工具的安装使用
- cordova打包app热更新问题
- 【web前端】小人行走
- 几款好用的报表制作软件!!!
- vscode Markdown TOC 插件生成目录去除autoauto
- python读取大文件md5校验性能优化比较
- BZOJ 4043 [Cerc2014] Vocabulary
- codeforces C2. Pokémon Army (hard version)(模拟)