HashMap每次扩容为什么是2倍

 更新时间:2024年11月24日 11:52:30   作者:zhangjin1120  
当HashMap在初始化没有指定容量的情况下,首次添加元素时,数组的容量为16;当超出阈值,数组容量为扩容为之前的2倍,为什么HashMap每次扩容都是之前的2倍?下面就介绍一下

当HashMap在初始化没有指定容量的情况下,首次添加元素时,数组的容量为16;当超出阈值,数组容量为扩容为之前的2倍。

为什么HashMap每次扩容都是之前的2倍?而不是像ArrayList首次为10,后续为1.5倍呢?2倍不是很浪费空间吗?

HashMap的putVal方法源码,如下图所示:

其中 n 为数组的长度,n - 1 为数组的最大索引值。(n - 1) & hash 的意思是将每个元素的key的hash值,与最大索引值-1进行相与操作,得出该元素在数组中的位置。hash是添加的元素进过哈希函数计算出来的值。

每次扩容后的数组长度如下表:

与运算的规则如下,只要有一个0,结果就是0;两个同时为1,结果才是1。

1 & 0 = 0
0 & 1 = 0
1 & 1 = 1
0 & 0 = 0

假如HashMap的容量不是2的n次幂,设容量为10,二进制为01010,(n-1)的二进制是01001,向里面添加同样的元素9,12,13,15,结果为:

可以看出,9,13,15得出的结果都是9,index相同,hash碰撞严重。

当HashMap的容量是16时,它的二进制是10000,(n-1)是15,二进制表示是01111,和hash值9,12,13,15进行与运算,计算结果如下:

还是9,12,13,15。可以看出,与运算后得出不同的值,使得添加的元素能够均匀分布在集合中不同的位置上,避免hash碰撞。

综上所述,HashMap计算添加元素的位置时,使用的位运算,这是高效的运算;

另外,HashMap的初始容量是2的n次幂,扩容也是2倍的形式进行扩容,是因为容量是2的n次幂,可以使得添加的元素均匀分布在HashMap中的数组上,减少hash碰撞,避免形成链表的结构,使得查询速度降低!

到此这篇关于HashMap扩容为什么是2倍的文章就介绍到这了,更多相关HashMap扩容2倍内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于java查找并打印输出字符串中字符出现次数

    基于java查找并打印输出字符串中字符出现次数

    这篇文章主要介绍了基于java查找并打印输出字符串中字符出现次数,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-11-11
  • 轻松理解Java面试和开发中的IoC(控制反转)

    轻松理解Java面试和开发中的IoC(控制反转)

    在Java开发中,IoC意 味着将你设计好的类交给系统去控制,而不是在你的类内部控制。这称为控制反转。下文给大家介绍Java面试和开发中的IoC(控制反转)知识,需要的朋友参考下吧
    2017-07-07
  • java结束进程的实例代码

    java结束进程的实例代码

    java结束程序进程的方法很简单,只要一句代码就行,大家参考使用吧
    2013-12-12
  • Java文件读写详解

    Java文件读写详解

    在真实的应用场景中,很多时候需要使用 Java 读写文件。比如说,读取配置文件信息、读取用户输入等。本篇文章将会详细介绍 Java 文件读写的相关知识,其中包括:读取文件、写入文件、复制文件和删除文件等操作,需要的朋友可以参考下
    2023-05-05
  • IntelliJ IDEA查看方法说明文档的图解

    IntelliJ IDEA查看方法说明文档的图解

    今天小编就为大家分享一篇关于IntelliJ IDEA查看方法说明文档的图解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-10-10
  • Java 轮询锁使用时遇到问题解决方案

    Java 轮询锁使用时遇到问题解决方案

    这篇文章主要介绍了Java 轮询锁使用时遇到问题解决方案,当我们遇到死锁之后,除了可以手动重启程序解决之外,还可以考虑使用顺序锁和轮询锁,但是过程也会遇到一些问题,接下来我们一起进入下面文章了解解决方案,需要的小伙伴可以参考一下
    2022-05-05
  • Java实现输出数字三角形实例代码

    Java实现输出数字三角形实例代码

    大家好,本篇文章主要讲的是Java实现输出三角形实例代码,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览
    2022-01-01
  • SpringBoot整合Redis实现热点数据缓存的示例代码

    SpringBoot整合Redis实现热点数据缓存的示例代码

    这篇文章主要介绍了SpringBoot中整合Redis实现热点数据缓存,本文以IDEA + SpringBoot作为 Java中整合Redis的使用 的测试环境,结合实例代码给大家详细讲解,需要的朋友可以参考下
    2023-03-03
  • spring boot3整合AI组件及使用方法

    spring boot3整合AI组件及使用方法

    本文介绍了springboot开发后端服务中,AI组件(Spring AI)的整合与使用,本文通过实例代码给大家介绍的非常详细,感兴趣的朋友跟随小编一起看看吧
    2024-05-05
  • Spring基于注解的缓存声明深入探究

    Spring基于注解的缓存声明深入探究

    spring boot对缓存支持非常灵活,我们可以使用默认的EhCache,也可以整合第三方的框架,只需配置即可,下面这篇文章主要给大家介绍了关于SpringBoot学习之基于注解缓存的相关资料,需要的朋友可以参考下
    2022-08-08

最新评论