HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式

HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式接着上一篇博客 上一篇博客说明了 HashMap 的初始容量都是 2 的 n 次幂的形式存在的 而扩容也是 2 倍的原来的容量进行扩容 也就是扩容后的容量也是 2 的 n 次幂的形式存在的 下面就来说明一下为什么是 2 的 n 次幂的形式 先来看一下源码 也就是向 HashMap 中添加元素 或者扩容时是怎么存放元素的 第一个截图是向 HashMap 中添加元素 putVal 方法的部分源码 可以看出 向集合

  接着上一篇博客,上一篇博客说明了HashMap的初始容量都是2的n次幂的形式存在的,而扩容也是2倍的原来的容量进行扩容,也就是扩容后的容量也是2的n次幂的形式存在的,下面就来说明一下为什么是2的n次幂的形式!

  先来看一下源码,也就是向HashMap中添加元素,或者扩容时是怎么存放元素的。

HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式

HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式

  第一个截图是向HashMap中添加元素putVal()方法的部分源码,可以看出,向集合中添加元素时,会使用(n – 1) & hash的计算方法来得出该元素在集合中的位置;而第二个截图是HashMap扩容时调用resize()方法中的部分源码,可以看出会新建一个tab,然后遍历旧的tab,将旧的元素进过e.hash & (newCap – 1)的计算添加进新的tab中,也就是(n – 1) & hash的计算方法,其中n是集合的容量,hash是添加的元素进过hash函数计算出来的hash值。

  HashMap的容量为什么是2的n次幂,和这个(n – 1) & hash的计算方法有着千丝万缕的关系,符号&是按位与的计算,这是位运算,计算机能直接运算,特别高效,按位与&的计算方法是,只有当对应位置的数据都为1时,运算结果也为1,当HashMap的容量是2的n次幂时,(n-1)的2进制也就是*111这样形式的,这样与添加元素的hash值进行位运算时,能够充分的散列,使得添加的元素均匀分布在HashMap的每个位置上,减少hash碰撞,下面举例进行说明。

  当HashMap的容量是16时,它的二进制是10000,(n-1)的二进制是01111,与hash值得计算结果如下:

HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式

上面四种情况我们可以看出,不同的hash值,和(n-1)进行位运算后,能够得出不同的值,使得添加的元素能够均匀分布在集合中不同的位置上,避免hash碰撞。

  下面就来看一下HashMap的容量不是2的n次幂的情况,当容量为10时,二进制为01010,(n-1)的二进制是01001,向里面添加同样的元素,结果为:

HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式

可以看出,有三个不同的元素进过&运算得出了同样的结果,严重的hash碰撞了。

终上所述,HashMap计算添加元素的位置时,使用的位运算,这是特别高效的运算;另外,HashMap的初始容量是2的n次幂,扩容也是2倍的形式进行扩容,是因为容量是2的n次幂,可以使得添加的元素均匀分布在HashMap中的数组上,减少hash碰撞,避免形成链表的结构,使得查询效率降低!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/230173.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午2:58
下一篇 2026年3月16日 下午2:58


相关推荐

  • Pytest(1)安装与入门[通俗易懂]

    Pytest(1)安装与入门[通俗易懂]pytest介绍pytest是python的一种单元测试框架,与python自带的unittest测试框架类似,但是比unittest框架使用起来更简洁,效率更高。根据pytest的官方网站介绍,它

    2022年7月29日
    10
  • python excel 转json

    python excel 转jsonpythonexcel 转 json 新建 base 文件夹 把所有 excel 复制进去 base 文件夹和 py 文件同级 importosimpo base forroot ds fsinos walk base forfinfs iff endswith suf

    2026年3月18日
    2
  • TranslateMessage 和 DispatchMessage

    TranslateMessage 和 DispatchMessageTranslateMes amp msg TranslateMes 是用来把快捷键消息转换为字符消息 并将转换后的新消息投递到调用线程的消息队列中 由于 Windows 对所有键盘编码都是采用虚拟键的定义 这样当按键按下时 并不得字符消息 需要键盘映射转换为字符的消息 字符消息被投递到调用线程的消息队列中 当下一次调用 GetMessage 函数时被取出

    2026年3月19日
    2
  • 邬贺铨:人工智能从生成式大模型向AI Agent和Agentic AI发展,互联网进入智能体时代

    邬贺铨:人工智能从生成式大模型向AI Agent和Agentic AI发展,互联网进入智能体时代

    2026年3月15日
    3
  • webservice传参数_java有参构造方法

    webservice传参数_java有参构造方法一、获取接口信息:  使用工具soapUI获取接口调用信息:  双击request:复制接口调用格式:webService接口通常传递xml参数因此需要组装数据: ①若传递单个参数则:<soapenv:Envelopexmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"xmlns:cen…

    2022年10月16日
    7
  • Nodejs安装及配置

    Nodejs安装及配置Nodejs 的安装及配置详细教程本文更新于 2020 12 2 如果时间太久已失效 请留言本教程使用虚拟机全新环境进行演示 如未安装过 Nodejs 几乎 100 安装配置成功 如未成功 请洗脸重试 下载 Nodejs 进入 Nodejs 官网 https nodejs org zh cn 选择下载最新版 也可以选择稳定的版本 个人喜欢用新的安装 Nodejs 双击下载的安装包点击 Next 开始进入安装勾选 Iacceptthete

    2026年3月18日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号