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

2023-05-16

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

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

  第一个截图是向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进制也就是1111111***111这样形式的,这样与添加元素的hash值进行位运算时,能够充分的散列,使得添加的元素均匀分布在HashMap的每个位置上,减少hash碰撞,下面举例进行说明。

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

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

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

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • 如何在Python中简单地解决Microsoft Visual C++ 14.0报错?

    问题简述 在 Windows 系统上 xff0c 我使用 Python 3 11 的 pip 工具安装 lxml 等库时会出现以下报错 error Microsoft Visual C 43 43 span class token numb
  • [图]python实现图的遍历、最小生成树、最短路径

    目录 1 图遍历 2 最小生成树 Prime算法 3 最短路径 Dijkstra算法 图的两种常用的表示方式是邻接矩阵和邻接表 以下以邻接矩阵为例 xff0c 图的初始化定义 xff1a class Graph def init self
  • C++经典类库

    现实中 xff0c C 43 43 的库门类繁多 xff0c 解决的问题也是极其广泛 xff0c 库从轻量级到重量级的都有 本文为你介绍了十一种类库 xff0c 有我们常见的 xff0c 也有不常见的 xff0c 一起来看 C 43 43
  • 防火墙开启后docker容器启动失败

    问题 xff1a 由iptables切换到firewall xff0c 发现redis的docker镜像启动不了 xff0c 报如下错误 xff1a ERROR for docker php redis 1 Cannot start ser
  • ubuntu如何分区

    1 swap交换分区 xff0c 一般为你机器内存的两倍 xff0c 少于这个容量 xff0c 系统无法进入休眠 实质是硬盘上的交换空间而非分区 xff0c 所以没有格式 xff0c 默认休眠将数据储存于此 可以取消 xff08 如不用sw
  • Networkx_找出最大联通子图及联通子图规模排序

    G 61 nx path graph 4 生成一个包含4个节点的线型网络 xff08 一字长蛇型 xff09 xff0c 节点编号lebel从0到1 span style font size 18px strong nx draw G wi
  • databinding简单使用

    开始使用分为4步 xff1a 第一步 数据绑定支持 xff0c 在app的build gradle下面添加数据绑定支持 android dataBinding enabled 61 true 第二步 xff1a 创建实体类 xff0c 如U
  • java使用线程池和Future接口实现异步的实例

    线程池可以提供线程的复用和管理 xff0c 避免线程频繁创建和销毁的开销 而Future接口则可以获取异步任务的执行结果和状态 xff0c 避免了阻塞等待异步任务完成的情况 下面是一个简单的示例代码 xff1a 96 96 96 impor
  • 我程序人生的启蒙书

    是这本书 xff0c 大一的我接触了c和c 43 43 xff0c 为数学专业的我打开了通往另一个世界的道路 xff0c 做一名优秀的程序员 是这本书 xff0c 大一的我开始废寝忘食的学习 xff0c 自习室里往往就放着这一本数 xff0
  • Leetcode Decode Ways 解题报告

    A message containing letters from A Z is being encoded to numbers using the following mapping 39 A 39 gt 1 39 B 39 gt 2
  • 研究生计算机专业的方向有哪些?

    链接 xff1a https www zhihu com question 349899328 answer 1752872326 编辑 xff1a 深度学习与计算机视觉 声明 xff1a 仅做学术分享 xff0c 侵删 作者 xff1a
  • Android Studio使用OpenCV进行图像基本处理

    Android Studio使用OpenCV进行图像基本处理 1 环境配置 进入OpenCV官网下载SDK包 进入官网 xff08 https opencv org releases xff09 选择 34 Android 34 版本下载
  • QT中基于QWebEngineView的C++和JS互相调用

    QT版本5 14 2 xff0c ubuntu18 04 4 1 PRO包含库 QT 43 61 webenginewidgets 2 main中启用OpenGL QCoreApplication setAttribute Qt AA Us
  • cin相关函数

    cin cin的相关函数 get getline gt gt ignore cin cout 都关联一个行缓冲区 按下enter键 xff0c 生成一个 n 在缓冲区中 xff0c 同时也就可以操作这一行了 cin get 从缓冲区取一个字
  • 浅谈人工智能(AI)

    人工智能 AI 一 人工智能简介 1 1 人工智能定义和发展历史 人工智能 xff08 Artificial Intelligence xff09 xff0c 英文缩写为AI 它是研究 开发用于模拟 延伸和扩展人的智能的理论 方法 技术及应
  • ubuntu18.04忘记密码的解决办法

    大半年没动的U盘系统忘了用户登录密码 xff0c root密码也忘记 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 xff01 简单记录一下 xff0c
  • iocp 非阻塞Socket异步接收限速

    网上找遍了也没找到关于异步非阻塞Socket的限速资料 于是 自己写了一份 限速100M S 误差15M S 限速50M S 误差5M S 限速10M S 误差0 3M S 限速5M S 误差0 02M S 限速越小 精度越准 functi
  • qt发布的程序时如何将依赖的dll分开放在不同目录下

    qt发布的程序时如何将依赖的dll分开放在不同目录下 QT发布的程序 xff0c exe可执行程序与dll文件都在同一个目录下 xff0c 我现在想把那些dll文件 xff0c 放到一个文件夹下 xff0c 这个文件夹和exe在同一个目录下
  • Android性能优化:Bitmap详解&你的Bitmap占多大内存?

    在开发app时 xff0c 显示一张本地图片 xff0c 这张图片在加载时会占用大多内存呢 xff1f 猜测占用内存大小和以下几个因素有关 xff1a 设计师切图 xff0c 图片本身的分辨率 xff1b 图片所放文件夹代表的 密度 dpi
  • HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式

    HashMap的初始容量都是2的n次幂的形式存在的 xff0c 而扩容也是2倍的原来的容量进行扩容 xff0c 也就是扩容后的容量也是2的n次幂的形式存在的 xff0c 下面就来说明一下为什么是2的n次幂的形式 xff01 先来看一下源码