提交 ef55d4b7 编写于 作者: 檀越@新空间's avatar 檀越@新空间 🐭

fix:hashmap的高位和低位

上级 a3ddd083
...@@ -706,12 +706,14 @@ public class HashMap<K, V> extends AbstractMap<K, V> ...@@ -706,12 +706,14 @@ public class HashMap<K, V> extends AbstractMap<K, V>
threshold = Integer.MAX_VALUE; threshold = Integer.MAX_VALUE;
return oldTab; return oldTab;
} else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && } else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
oldCap >= DEFAULT_INITIAL_CAPACITY) //新cap是旧cap的2倍,并且旧cap大于16 oldCap >= DEFAULT_INITIAL_CAPACITY){
//新cap是旧cap的2倍,并且旧cap大于16
//阈值翻倍 //阈值翻倍
newThr = oldThr << 1; newThr = oldThr << 1;
} else if (oldThr > 0) }
} else if (oldThr > 0) {
newCap = oldThr;//旧阈值大于0 newCap = oldThr;//旧阈值大于0
else {//如果初始化的时候用户什么都没传,那么此时oldCap和oldThr都==0 } else {//如果初始化的时候用户什么都没传,那么此时oldCap和oldThr都==0
//将默认容量大小DEFAULT_INITIAL_CAPACITY(16)赋给newCap(新Node数组的长度) //将默认容量大小DEFAULT_INITIAL_CAPACITY(16)赋给newCap(新Node数组的长度)
newCap = DEFAULT_INITIAL_CAPACITY; newCap = DEFAULT_INITIAL_CAPACITY;
//将(默认负载因子)0.75f * (默认的容量大小)DEFAULT_INITIAL_CAPACITY的计算结果,赋值给newThr(新的扩容阀值) //将(默认负载因子)0.75f * (默认的容量大小)DEFAULT_INITIAL_CAPACITY的计算结果,赋值给newThr(新的扩容阀值)
...@@ -742,18 +744,20 @@ public class HashMap<K, V> extends AbstractMap<K, V> ...@@ -742,18 +744,20 @@ public class HashMap<K, V> extends AbstractMap<K, V>
if (e.next == null) {//如果该Node元素的next==null,则说明该Node元素后边既没有链表又没有红黑树 if (e.next == null) {//如果该Node元素的next==null,则说明该Node元素后边既没有链表又没有红黑树
//则将该Node元素直接存于新Node数组的指定位置 //则将该Node元素直接存于新Node数组的指定位置
newTab[e.hash & (newCap - 1)] = e; newTab[e.hash & (newCap - 1)] = e;
} else if (e instanceof TreeNode) {//如果该Node元素后边跟着的是一个红黑树结构 } else if (e instanceof TreeNode) {//如果该Node元素后边跟着的是一个红黑树结构
//在新的Node数组中,将该红黑树进行拆分 //在新的Node数组中,将该红黑树进行拆分
//如果拆分后的子树过小(子树的节点小于等于6个),则取消树化,即将其转为链表结构 //如果拆分后的子树过小(子树的节点小于等于6个),则取消树化,即将其转为链表结构
((TreeNode<K, V>) e).split(this, newTab, j, oldCap); ((TreeNode<K, V>) e).split(this, newTab, j, oldCap);
} else { } else {
//新的位置只有两种可能:原位置,原位置+老数组长度 /**
//把原链表拆成两个链表,然后再分别插入到新数组的两个位置上 * 新的位置只有两种可能:原位置,原位置+老数组长度
//不用多次调用put方法 * 把原链表拆成两个链表,然后再分别插入到新数组的两个位置上
//如果是链表的情况下,则进行下面的链表数据转移的操作 * 不用多次调用put方法
//分别是原位置不变的链表和原位置+原数组长度位置的链表 * 如果是链表的情况下,则进行下面的链表数据转移的操作
*/
//分别是原位置不变的链表
Node<K, V> loHead = null, loTail = null; Node<K, V> loHead = null, loTail = null;
//原位置+原数组长度位置的链表
Node<K, V> hiHead = null, hiTail = null; Node<K, V> hiHead = null, hiTail = null;
Node<K, V> next; Node<K, V> next;
do { do {
...@@ -772,10 +776,8 @@ public class HashMap<K, V> extends AbstractMap<K, V> ...@@ -772,10 +776,8 @@ public class HashMap<K, V> extends AbstractMap<K, V>
loTail = e; loTail = e;
} else {//如果e.hash&oldCap进行与运算,算出的结果不为0,则更新该Node节点所对应的数组下标 } else {//如果e.hash&oldCap进行与运算,算出的结果不为0,则更新该Node节点所对应的数组下标
if (hiTail == null) { if (hiTail == null) {
hiHead = e; hiHead = e;
} else { } else {
hiTail.next = e; hiTail.next = e;
} }
hiTail = e; hiTail = e;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册