简述 HashMap 扩容机制
HashMap基础
【注意】以下内容只是针对 JDK1.8
HashMap继承了AbstractMap类,实现了Map,Cloneable,Serializable接口。
其使用 hash 算法来决定元素的存储,hash 表包含如下属性。
- 容量(capacity):hash 表数组的大小,默认为16;
- 初始化容量(initial capacity):创建 hash 表时指定的初始容量;
- 尺寸(size):当前 hash 表中记录的数量;
- 负载(load):负载等于 “ size / capacity ”。负载为 0 时,表示空的 hash 表。轻负载的 hash 表具有冲突少、适宜插入和查询的特点。(但太小的话,又会增加占用的内存开销)。
- 负载因子(load factor):决定 hash 表的最大填满程度,范围是 0~1,默认为 0.75 。
当 hash 表的负载达到了指定的 “负载因子” 值时,hash 表就会加倍扩容,并将原有的对象重新分配,放入新的表中,这称为 rehashing 。rehashing 过程很复杂,而已非常消耗性能,所以指定一个合适的 “负载因子” 值很重要。
当 size / capacity > 负载因子,即 size(当前记录数) > 负载因子 * capacity(容量) 时,hash 会扩容。
HashMap的容量,默认是16
/**
* The default initial capacity - MUST be a power of two.
*/
static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
HashMap的加载因子,默认是0.75
/**
* The load factor used when none specified in constructor.
*/
static final float DEFAULT_LOAD_FACTOR = 0.75f;
当 HashMap 中元素个数超过 容量 * 加载因子 时,HashMap会进行扩容。即默认情况下,当 HashMap 中元素超过12个就会扩容
扩容多大?
HashMap 扩容是为当前容量 * 2,也就是成倍扩容。
【问题1】为什么每次扩容的倍数是2,而不是1.5或者2.5 ?
理论上,扩容倍数用多少都行,1.5, 2.5 ,3.5都可以的,都能实现HashMap。
实际上,HashMap选用了2倍,是为了做一个优化。
因为计算哈希值的时候是使用取模运算,而HashMap的开发者想要优化下这个取模运算的速度,那么他就需要把HashMap内部的数组长度固定为 2^n 的长度了,也就是说HashMap里面的数组的长度,始终都是2的n次幂。为了实现这个效果,它的扩容因子很自然就是2倍了。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了