当前位置:网站首页>e.hash & oldCap == 0 详细解读
e.hash & oldCap == 0 详细解读
2022-06-22 05:58:00 【小爽帅到拖网速】
e.hash & oldCap == 0 详细解读
按(e.hash & oldCap) 是否等于0分两种情况(推导过程中要时刻留意:扩容前后的数组长度都为2的n次幂,这个是HashMap底层源码规定的):
情况1:【推导过程1】当e.hash&oldCap等于0时,e在新旧数组中的索引位置不变:(2oldCap-1)& e.hash = (oldCap -1) & e.hash
情况2:【推导过程2】当e.hash&oldCap不等于0的元素,e在新数组中的索引位置是其在旧数组中索引位置的基础上再加上旧数组长度个偏移量: (2oldCap-1)& e.hash = (oldCap -1) &e.hash+oldCap
oldCap 是table的容量,按照源码的策略,一定是2^n次方,也就代表着该2进制一定只有一个1,剩余的都是0;如果想要保证e.hash&oldCap ==0,则只需要e.hash在对应oldCap二进制位在1的那位为0,就可以保证最后的按位与操作(&)结果为0;如果e.hash&oldCap !=0 ,则只需要e.hash在对应oldCap二进制位在1的那位为1,就可以保证最后的按位与 操作(&)不等于0
假设 oldCap = 16 = 2^4 = 10000(二进制)
推导过程1:
想要满足e.hash&oldCap ==0,假设 e.hash = 01111 (注意,这里的e.hash经过最初的hash(key)计算的),注意这个01111中0的位置是对应着oldCap 二进制中唯一的那位1的位置)
10000 & 01111
则oldCap & e.hash = 10000 & 01111 = 00000(二进制) = 0(十进制)
在添加元素的时候,是通过这种计算方式来为即将添加的元素在数组中找到对应的下标

而现在我们是将数组容量扩容到了两倍,公式肯定要有所修改
(2oldCap-1)& e.hash = (2^5 - 1)& 0 1111 = 01 1111 & 0 1111 = 00 0000(二进制)= 0(十进制)
(oldCap -1)& e.hash = (2^4 - 1)& 0 1111 = 0 1111 & 0 1111 = 0 0000(二进制) = 0 (十进制)
由此可见,如果满足 e.hash&oldCap ==0 ,旧数组中元素的下标位置在新数组的元素下标的位置是一样的
(e.hash & oldCap) == 0
if (loTail != null) {
loTail.next = null;
// 旧数组中元素的下标位置在新数组的元素下标的位置是一样的
newTab[j] = loHead;
}
推导过程2:
想要满足e.hash&oldCap !=0,假设e.hash = 11111(注意,这里的e.hash经过最初的hash(key)计算的),注意这个11111中第一个1的位置是对应着oldCap 二进制中唯一的那位1的位置)
10000 & 11111
则oldCap & e.hash = 1 0000 & 1 1111 = 1 0000 (二进制) = 16(十进制)
在添加元素的时候,是通过这种i = (n - 1) & hash计算方式来为即将添加的元素在数组中找到对应的下标
(2oldCap-1)& e.hash = (2^5 - 1)& 1 1111 = 01 1111 & 1 1111 = 0001 1111(二进制)= 31(十进制)
(oldCap -1)& e.hash = (2^4 - 1)& 1 1111 = 0 1111 & 1 1111 = 0000 1111(二进制) = 15 (十进制)
可以发现 (oldCap -1)& e.hash + oldCap = 15 + 16 = 31 = (2oldCap-1)& e.hash
由此可见,如果满足e.hash&oldCap != 0 ,旧数组中元素的下标位置 + 旧数组容量 = 元素在新数组中下标的位置
e.hash & oldCap) == 0
if (hiTail != null) {
hiTail.next = null;
newTab[j + oldCap] = hiHead;
}
以上仅为个人解读,如有误解,请在评论区指教,谢谢
边栏推荐
- 【Rust笔记】03-引用
- MFC tab control add Icon
- GeoSwath plus 技术和数据采集处理
- 生信文献学习(part1)--PRECISE: a ... approach to transfer predictors of drug response from pre-clinical ...
- 单精度,双精度和精度(转载)
- Signal output library
- Linear regression: least squares, Tellson estimation, RANSAC
- 878. 第 N 个神奇数字 数学+二分
- TCP connection details
- EPP (enhanced parallel port)
猜你喜欢
随机推荐
虚职、架空、拖后腿,大厂开源办公室到底什么样?
Adaboost
从入门到精通之专家系统CLIPS(一)CLIPS初识与概述
生信可视化(part4)--相关性图
Improve your game‘s performance
BinaryFormatter saving and loading game data for unity
性能优化 之 3D资产优化及顶点数据管理
Shengxin visualization (Part2) -- box diagram
关于MNIST线性模型矩阵顺序问题
Unity encrypts ASE game data
Case analysis of terminal data leakage prevention
性能优化最佳实践之缩减游戏大小
402-字符串(题目:剑指Offer58-II.左旋转字符串、 28. 实现 strStr()、459.重复的子字符串)
matlab 的离散pid控制
Ethernet UDP frame contract design
R语言观察日志(part24)--writexl包
Logback自定义Pattern参数解析
常用CMOS模拟开关功能和原理
Shengxin visualization (Part3) -- violin diagram
Surfer格网文件裁剪









