Java HashMap

说明

此文档所介绍的HashMap是基于JDK1.8之后的。此文受到网上很多其他Java生态爱好者文章的影响,写此文的目的是系统的概括下HashMap,并把一些优秀文章的脉络连接起来起到目录作用。在此感谢优秀文章作者的启发,由于自身实力有限,若有纰漏之处还请评论指导。

原理(参考[1][3])

HashMap类似于HashTable,本质都是存储的键值对,也就是key、value,key用作存储初始索引,通过对其进行一系列运算把value映射存储到底层数据结构中。其存储的数据结构(JDK 1.8之后)如下:

数据结构(引用[1])

如上图所示,每个数组是有存储的是一个链表或者红黑树(视情况而定)

* 数组

* 链表

* 红黑树

存储过程

对key进行hash运算,得到key的hash值。

把key的hash值和hashMap的(length-1)进行&运算,得到index,index即为数据的索引下标,例如0,1,2,3。

根据索引下标,把该Entry存到对应的数据结构中。

计算索引下标,也就是keyHash&(length-1)时,不同的keyHash会产生同样的索引下标,也就是说一个数组元素可能会存储多个数据;

所以每个数组元素存储的是一个链表,当链表的长度超过TREEIFY_ THRESHOLD:8时,把链表改为红黑树。

graph LR;

key-->|进行Hash运算|key的hash值;

key的hash值-->|和hashMap的length-1进行&运算|数组下标index;

数组下标index-->|根据index存储该Entry也就是key, value|该index的数组元素数据结构被更新:链表或者红黑树插入该Entry;

HashMap的阈值(参考[1])

DEFAULT INITIAL CAPACITY:

数组的初始容量,也就是默认会数组初始长度为16,长度不能太大或者太小。如果太小,很容易触发扩容,如果太大,

遍历HashMap会比较慢。值: 1<<4; //16

MAXIMUM CAPACITY:

HashMap最大容量,一.般情况下只要内存够用,HashMap不会出现问题。值: 1<<30 (整数最大值的一半)

DEFAULT LOAD FACTOR:

默认的负载因子。因此初始情况下,当键值对的数量大于16 * 0.75 = 12时,就会触发扩容。值: 0.75f。

TREEIFY_ THRESHOLD:

如果哈希函数不合理,即使扩容也无法数组元素中链表的长度,因此Java 的处理方案是当链表太长

时,转换成红黑树。这个值表示当某个数组元素中,链表长度大于8时,有可能会转化成树。值: 8

UNTREEIFY _THRESHOLD:

在HashMap扩容时,如果发现链表长度小于6,则会由树重新退化为链表。值: 6

MIN_ TREEIFY_ CAPACITY:

在转变成树之前,还会有一次判断,只有键值对数量大于64才会发生转换。这是为了避免在HashMap建立初期,多

个键值对恰好被放入了同一个链表中而导致不必要的转化。值: 64

扩容(参考[2])

* 当元素超过数组长度的75%就会发生扩容,既长度增加一倍。

* 默认的数组长度```DEFAULT _INITIAL_ CAPACITY```=16,默认的负载因子```DEFAULT LOAD FACTOR```=0.75;当键值对数量超过16 * 0.75 = 12时,就会触发扩容导致数组长度变为16 * 2 = 32。

注意:扩容后,每个键值对数据存储的索引下标需要重新计算。通过公式:keyHash&(newLength-1)。结果会变成:newIndex = oldIndex + 扩容增加的长度。

性能(参考[4])

影响性能的因素

存储长度(数组长度):需要为2的整数次幂,此文[5]已经详细解释,就不重复造轮子。

扩容频率->负载因子:选择一个合适的负载因子,如果负载因子太小会导致扩容太频繁,从而导致性能损失。

实践案例

文章[4]已经为我们很好地举了一个提高性能的实践案例。

”比如说,我们有1000个元素new HashMap(1000), 但是理论上来讲new HashMap(1024)更合适,不过上面annegu已经说过,即使是1000,hashmap也自动会将其设置为1024。 但是new HashMap(1024)还不是更合适的,因为0.75*1000 < 1000, 也就是说为了让0.75 * size > 1000, 我们必须这样new HashMap(2048)才最合适,既考虑了&的问题,也避免了resize的问题。“

参考文章

[1]https://blog.csdn.net/weixin_45290108/article/details/100056621

[2]https://blog.csdn.net/wohaqiyi/article/details/81448176

[3]https://blog.csdn.net/woshimaxiao1/article/details/83661464

[4]https://blog.csdn.net/cnq2328/article/details/60783708

[5]https://blog.csdn.net/wohaqiyi/article/details/81161735

java map扩容机制_Java HashMap的原理、扩容机制、以及性能思考相关推荐

  1. java:Map借口及其子类HashMap五,identityHashMap子类

    java:Map借口及其子类HashMap五,identityHashMap子类 了解:identityHashMap子类 一般情况下,标准的Map,是不会有重复的key值得value的,相同的key ...

  2. java map原理_Java HashMap底层原理分析

    前两天面试的时候,被面试官问到HashMap底层原理,之前只会用,底层实现完全没看过,这两天补了补功课,写篇文章记录一下,好记性不如烂笔头啊,毕竟这年头脑子它记不住东西了哈哈哈.好了,言归正传,今天我 ...

  3. java map 泛型 反射_java - 反射操作泛型

    反射操作泛型 Java的泛型采用的是泛型擦除的机制,泛型仅仅是给编译器javac使用的,为了确保数据的安全性和免去强制类型转换的问题,一旦编译完成,所有和泛型有关的类型将全部擦除. 为了通过反射操作这 ...

  4. java map 自动排序_java Map排序问题

    java 中,Map常见的有HashMap ,TreeMap等等,Map是一个接口,我们不能直接声明一个Map类型的对象,在实际开发 中,比较常用的Map性数据结构是HashMap和TreeMap,它 ...

  5. java心跳机制_Java: server/client 心跳机制实现 示例

    心跳机制 心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制. 大部分CS的应用需要心跳机制.心跳机制一般在Server和Client都要实现,两者实现原理 ...

  6. java gc回收机制_Java中的GC回收机制

    为什么要进行GC回收? 当我们新建一个对象时,系统就会为其分配一定的内存空间,而有时候新建的对象没有去使用时,不回收的话会极大浪费内存空间,造成系统效率低下. 什么时候进行GC回收? 1.当CPU空闲 ...

  7. java map扩容机制_java中ConcurrentHashMap的扩容机制是怎样的?详细解析

    大家都知道java中有很多的基础知识,需要大家花费一定的时间去消化.关于java中ConcurrentHashMap 的扩容机制不知道大家是否了解过,其实内容也是很好理解的,一起来看看吧. 首先,我们 ...

  8. java map扩容机制_java中ConcurrentHashMap的扩容机制问题

    JDK8中,扩容函数transfer中有如下一段代码,如果槽内的结点为链表结点,把原链表的结点按照某位的元素是否为1,划分为两个链表,分别放置在nextTab[i]和nextTab[n+i]位置上, ...

  9. java的两种运行机制_Java☞JVM工作原理

    参考博客:1 2 3 JVM工作原理 java虚拟机体系结构 Java平台由Java虚拟机和Java应用程序接口搭建,Java语言则是进入这个平台的通道,用Java语言编写并编译的程序可以运行在这个平 ...

最新文章

  1. 7个Debug linux程序的Strace 列子
  2. unbuntu nginx安装详解 /configure: error: the HTTP rewrite module requires the PCRE library
  3. how can we make them work together efficiently?
  4. unix中的grep家族
  5. html打开时按钮自动触发事件,html在用户按下按键时触发的事件属性onkeydown
  6. window snmp服务开启及测试
  7. java经典笔试题目_java笔试考题(经典).pdf
  8. 10kv开关柜价格_常用变压器、开关柜介绍、厂家联系方式、报价单分享
  9. 从服务器断开并删除套接字
  10. 16进制转10进制c 语言算法,16进制转换算成10进制程序
  11. 在线教育项目-npm install失败-下载依赖失败-(vue-admin-template-master)
  12. 开源项目学习:XINS
  13. wifi自动连接,断开连接,打开和关闭,亲测有效
  14. 读后感:【许岑—如何成为有效学习的高手】
  15. Shell IFS变量
  16. 研究 | CT图像迭代重建算法研究进展
  17. Autodesk 开源 3D 打印机
  18. 奥哲低代码助力西子联合自主搭建航空QMS
  19. notepad++格式化XML
  20. 浅谈敏捷开发中的设计

热门文章

  1. 人为何会生病?(1)
  2. win10 设置定时关机
  3. java 数组去除重复_Java从数组中删除重复项?
  4. 精通 CSS+DIV 网页样式与布局 55
  5. Microsoft.Office.Interop.Word 创建word
  6. JAVA通过auth_code获取支付宝账户信息
  7. 从零开始开发Android相机app(三)简单介绍图像滤镜功能
  8. JAVA计算机毕业设计宠物购物系统Mybatis+系统+数据库+调试部署
  9. TP5框架的多图片上传返回不显示问题
  10. C语言校园家教管理系统