原文作者:很閒很快樂

原文地址:HashMap初始容量为什么是2的n次幂及扩容为什么是2倍的形式

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碰撞,避免形成链表的结构,使得查询效率降低!

Java集合—HashMap为什么2倍扩容相关推荐

  1. Java集合HashMap

    HashMap Map接口的一个实现类 用于存储键值对映射关系 重复键 如果,出现重复键,将覆盖原有键的Value值 package bhz.aio;import java.util.HashMap; ...

  2. Java集合—HashMap底层原理

    原文链接:最通俗易懂搞定HashMap的底层原理 HashMap的底层原理面试必考题.为什么面试官如此青睐这道题?HashMap里面涉及了很多的知识点,可以比较全面考察面试者的基本功,想要拿到一个好o ...

  3. Java集合——HashMap、HashTable以及ConCurrentHashMap异同比较

    转发:https://www.cnblogs.com/zx-bob-123/archive/2017/12/26/8118074.html 0. 前言 HashMap和HashTable的区别一种比较 ...

  4. 深入java集合-HashMap

    本文为读书笔记,书籍为java并发编程的艺术 hashmap资料来自b站黑马 文章目录 1.HashMap 1.1 HashMap成员变量 问题: 为什么必须是2的n次幂?如果输入值不是2的幂比如10 ...

  5. 分析了解JDK1.8版本的Java集合HashMap的put()方法

    hashMap是java最常用的Key-Value形式的集合.了解其原理和底层代码是很有必要的,今天就记录下对HashMap的.put()方法的研究分析(元素添加方法): 先说下个人研究分析结果: H ...

  6. java集合 HashMap的三种遍历方式

    前言: HashMap的集合中的比重是无可厚非的,由自身的数组+链表/红黑树构成的(JDK 1.8),这样使得HashMap优点表现出来: 数组查询效率快: 链表的插入和删除效率也加快 但是HashM ...

  7. Java 集合 — HashMap

    HashMap 无序(每次resize的时候都会变) 非线程安全 key和value都看可以为null 使用数组和链表实现 查找元素的时候速度快 几个重要属性: loadFactor:用来计算thre ...

  8. Java集合- HashMap 的底层数据结构实现原理

    一.HashMap 的数据结构 JDK1.8 之前 JDK1.8 之前 HashMap 底层是 数组和链表 结合在一起使用也就是 链表散列. HashMap 通过 key 的 hashCode 经过扰 ...

  9. HashMap 为什么是2倍扩容

    我们通过源码来分析下,HashMap 为什么是2倍扩容, 看源码,得知通过计算(n - 1) & hash来确定key的索引位置,当HashMap的容量是2的n次幂时,n - 1的后几位数都是 ...

最新文章

  1. 无冬连接不上账号服务器,电脑中玩无冬online掉线怎么回事_电脑中玩无冬online游戏总是掉线如何修复...
  2. 追踪解析Spring ioc启动源码(2)
  3. Xilinx ISE 调用 ModelSim SE 库编译
  4. 最长公共子序列和追踪解
  5. php 文件 不更新,php页面不刷新更新数据
  6. 钓鱼邮件检测(本科毕设)
  7. HTML学生个人网站作业设计:动漫网站设计——悬崖上的金鱼姬(5页) HTML+CSS 简单DIV布局网页模板代码
  8. 喜讯 | 哈特公寓荣誉获最佳新锐公寓奖
  9. matlab批量读取图像图片并批量处理图像(以伽马校正为例)以及批量保存图像
  10. 百度地图申请KEY,定位和获取周边热点
  11. 2023年法定节假日配置Mysql
  12. TypeScripy-类的基本使用
  13. PTA - 电话聊天狂人
  14. IPv6解决方案ND防攻击技术白皮书
  15. svn文件图标不显示-解决方案
  16. 基于FPGA的除法器设计
  17. nmap 端口说明和扫描顺序
  18. Python简单理解1-10阶乘和运算
  19. 微信小程序录音功能实现、录音转文字(接口与插件的实现)
  20. 信息系统项目管理师就业前景分析

热门文章

  1. [记录]java.math.biginteger cannot be cast to java.lang.long
  2. 谁是最好的Coder
  3. Linux下root密码丢失和运行级别错误的解决办法
  4. 有关ArcGIS Server Server URL问题
  5. 利用js实现popup弹窗
  6. Java当中的IO一
  7. Vue.js 入门指南之“前传”(含sublime text 3 配置)
  8. mac 环境变量设置
  9. GridView合并列下的行单元格的方法
  10. hdu 2025 查找最大元素