HashMap 扩容原理

Posted learning_code_blog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HashMap 扩容原理相关的知识,希望对你有一定的参考价值。

今天有个朋友问我, 为啥hashMap扩容之后 数组的位置是 当前位置 或 当前位置 + oldCap 呢?

想了一下,举个例子最清楚了

我们模拟一下就清楚了,分别用两个key 进行确认数组位置  .我们默认全部每次扩容都是计算hash出来的结果
默认两个key 
key1.hash = 40 转换成二进制 101000
key2.hash = 19 转换成二进制 010011

默认数组长度  16 ==> 转换二进制 10000 , 由于是 newTab[e.hash & (newCap - 1)] = e;  所以最终 15 = 01111 

默认分配 
key1.hash = 40  与 19 

101000  40
001111  15
-------
001000 在数组第8位


key2.hash = 19 转换成二进制 010011

010011   19
001111   15
------
000011  在第3位

=================================================扩容之后===========================
 
默认数组长度  16<<1 = 32 ==> 转换二进制 100000 , 由于是 newTab[e.hash & (newCap - 1)] = e;  所以最终 31 = 011111

key1.hash = 40  与 19 
0101000  40
0011111  31
-------
0001000 在数组第8位

key2.hash = 19 转换成二进制 100011

0010011   19
0011111   31
-------
0010011 在第19位 等于 原长度oldLen16 + 之前所有位置3 

如果每次都这样就算,太浪费时间了
所以找寻规律

发现是否需要 加上原长度  只要将自己的hash 和oldLen(16)进行一次&就可以了


key1.hash = 40 转换成二进制 101000 位置在 8
key2.hash = 19 转换成二进制 010011 位置在3 

扩容判断 -- 每次都全量计算hash 性能很差, 可以做一次优化
key1.hash= 40 

0101000  40
0010000  16
--------
0000000  0   = 0 ?还是在原先位置 

key2.hash = 19
0010011  19
0010000  16
--------
0010000  16 !=0 那就是需要 newTab[j + oldCap] = hiHead; 

以上是关于HashMap 扩容原理的主要内容,如果未能解决你的问题,请参考以下文章

HashMap原理 — 扩容机制及存取原理

HashSet保证元素唯一原理以及HashMap扩容机制

HashMap的扩容机制---resize()

HashMap底层详解-003-resize并发下的安全问题

HashMap原理 扩容机制及存取原理

hashmap底层实现原理是啥?