e.hash oldCap == 0 详细解读
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 1111(二进制)= 15(十进制)
(oldCap -1)& e.hash = (2^4 - 1)& 0 1111 = 0 1111 & 0 1111 = 0 1111(二进制) = 15 (十进制)
由此可见,如果满足 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;
}
以上仅为个人解读,如有误解,请在评论区指教,谢谢
e.hash oldCap == 0 详细解读相关推荐
- HashMap扩容时的rehash方法中(e.hash oldCap) == 0算法推导
PS:由于文档是我在本地编写好之后再复制过来的,有些文本格式没能完整的体现,故提供下述图片,供大家阅览,以便有更好的阅读体验: HashMap在扩容时,需要先创建一个新数组,然后再将旧数组中的数据转移 ...
- 提升不止一点点,Dubbo 3.0 预览版详细解读
Dubbo 自 2011 年 10 月 27 日开源后,已被许多非阿里系的公司使用,其中既有当当网.网易考拉等互联网公司,也不乏中国人寿.青岛海尔等大型传统企业.更多用户信息,可以访问Dubbo @G ...
- 等保测评2.0超详细解读,收藏这一篇就够了
一.等级保护介绍 1.1什么是等级保护 网络安全等级保护是指对国家重要信息.法人和其他组织及公民的专有信息以及信息和存储.传输.处理这些信息的信息系统分等级实行安全保护,对信息系统中使用的信息安全产品 ...
- MemCache超详细解读
MemCache是什么 MemCache是一个自由.源码开放.高性能.分布式的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高 ...
- MemCache详细解读
MemCache是什么 MemCache是一个自由.源码开放.高性能.分布式的分布式内存对象缓存系统,用于动态Web应用以减轻数据库的负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高 ...
- WannaCry 勒索病毒复现及分析,蠕虫传播机制全网源码详细解读 | 原力计划
作者 | 杨秀璋,责编 | 夕颜 来源 | CSDN博客 头图 | CSDN 下载自东方 IC 出品 | CSDN(ID:CSDNnews) 这篇文章将详细讲解WannaCry蠕虫的传播机制,带领大家 ...
- WannaCry勒索病毒复现及分析,蠕虫传播机制全网源码详细解读 | 原力计划
作者 | 杨秀璋 编辑 | 夕颜 题图 | 东方 IC 出品 | CSDN(ID:CSDNnews) 这篇文章将详细讲解WannaCry蠕虫的传播机制,带领大家详细阅读源代码,分享WannaCry勒索 ...
- NLP突破性成果 BERT 模型详细解读 bert参数微调
https://zhuanlan.zhihu.com/p/46997268 NLP突破性成果 BERT 模型详细解读 章鱼小丸子 不懂算法的产品经理不是好的程序员 关注她 82 人赞了该文章 Goo ...
- VINS-mono详细解读与实现
VINS-mono详细解读 VINS-mono详细解读 前言 Vins-mono是香港科技大学开源的一个VIO算法,https://github.com/HKUST-Aerial-Robotics/V ...
最新文章
- MATLAB格式化输出控制
- oracle怎么判断主库还是备库,Oracle查看归档是否被备库应用
- 神策数据杨宁:券商财富管理数字化转型客户全生命周期解读
- 撸过一万行代码,你看过这篇文章吗?
- webapi get请求 FromUri list参数传递
- 嵌入式Linux开发板上NFS文件系统的使用【ZT】
- 【干货】2020年陆奇最新万字演讲:世界新格局下的创业创新机会.pdf(附下载链接)...
- winform自定义分页控件
- C#显示当前日期时间
- Eclipse中,使用Darkest主题,static方法在main中不是斜体的解决办法
- 简历里计算机能力,简历上计算机能力怎么写
- shopnc route.php,shopnc商城专题页的伪静态支持
- 给微信小程序配一个App如何?
- 3D建模入门学习方法,制作过程的六个主要阶段讲解 小白教程
- 蒲公英分布平台下载更新实现
- Linux 操作系统的 ECS 挂载云硬盘
- kali安装teamviewer
- 【C语言编程1】删除数组中重复元素,并排序
- Mysql 密码忘记了,呃呃呃
- 电力线载波抄表系统--功能特征