当前位置: 首页 > news >正文

解刨HashMap的put流程 <二> JDK 1.8

好的,我们接着 HashMap 的put流程往下讲)。第一步已经计算出了 Key 的哈希值,第二步是 “计算元素的存储索引(即确定放在数组的哪个桶中)”。这一步是连接哈希值与实际存储位置的关键,核心目标是:将第一步计算出的哈希值(32 位整数,范围极大)“映射” 到数组的有效索引范围内(0 ~ 数组容量 - 1)。


一、核心操作:index = hash & (n - 1)

计算索引的公式非常简单:

int index = hash & (n - 1);

其中:

  • hash:第一步通过扰动函数处理后的哈希值(32 位整数);
  • n:当前 HashMap 数组的容量(如初始容量 16,扩容后 32、64 等,始终是 2 的幂);
  • n - 1:容量减 1(因n是 2 的幂,所以n-1的二进制一定是 “全 1”,如 n=16 时,n-1=15→二进制1111)。

二、为什么这样计算?

这个公式的设计有两个核心目的:确保索引有效保证分布均匀,且依赖于 “n是 2 的幂” 这个前提。

1. 确保索引一定在数组范围内

数组的索引必须是0 ~ n-1之间的整数(否则会数组越界)。
由于n是 2 的幂,n-1的二进制是 “全 1”(如 n=8→n-1=7→111),任何整数与 “全 1” 做&运算,结果只会保留该数的低k位(kn的幂次,如 n=8 是 2³,保留低 3 位),因此结果必然在0 ~ n-1范围内。

举例
n=8(2³),n-1=7(111):

  • 任意哈希值(如10010110)与111&运算:
    10010110 & 00000111 = 00000110(十进制 6)→ 索引 = 6(在 0~7 范围内)。
2. 等价于取模运算,但效率更高

n是 2 的幂时,hash & (n-1) 与 hash % n(取模运算)的结果完全相同,但位运算&的执行效率远高于取模运算%(计算机处理位运算更直接)。

举例
n=16(2⁴),hash=20:

  • 20 & 15 = 4(20 的二进制10100 & 15 的01111 = 00100);
  • 20 % 16 = 4(结果相同)。
3. 结合扰动函数,让索引分布更均匀

第一步的扰动函数已经让哈希值的高低位混合,增加了随机性。而n-1的 “全 1” 特性,能让哈希值的每一位都参与索引计算(不会浪费任何一位的特征),进一步减少不同哈希值映射到同一索引的概率(即减少哈希冲突)。

反例:如果n不是 2 的幂(如 n=10),则n-1=9(二进制1001),此时&运算只会用到哈希值的第 0 位和第 3 位,其他位的特征被忽略,会导致大量不同的哈希值映射到相同索引(冲突剧增)。


第二步的核心是通过hash & (n-1)计算索引,它依赖于两个关键设计:

  1. n是 2 的幂:保证n-1是 “全 1” 二进制,确保索引有效且与取模结果等价;
  2. 位运算&:比取模运算更快,且能充分利用哈希值的每一位特征。

这一步将大范围的哈希值 “压缩” 到数组的有效索引范围内,同时通过均匀分布减少冲突,为后续的元素插入和查询效率奠定基础。

http://www.lryc.cn/news/620518.html

相关文章:

  • 【自动驾驶】自动驾驶概述 ① ( 自动驾驶 与 无人驾驶 | 自动驾驶 相关岗位 及 技能需求 )
  • Day58--图论--117. 软件构建(卡码网),47. 参加科学大会(卡码网)
  • 从零开始的云计算生活——激流勇进,kubernetes模块之Pod资源对象
  • 解决EKS中KEDA访问AWS SQS权限问题:完整的IRSA配置指南
  • 【web站点安全开发】任务4:JavaScript与HTML/CSS的完美协作指南
  • 【论文阅读】基于卷积神经网络和预提取特征的肌电信号分类
  • 随身 Linux 开发环境:使用 cpolar 内网穿透服务实现 VSCode 远程访问
  • docker使用指定的MAC地址启动podman使用指定的MAC地址启动
  • vllmsglang 单端口多模型部署方案
  • 用飞算JavaAI一键生成电商平台项目:从需求到落地的高效实践
  • Java中加载语义模型
  • 【无标题】卷轴屏手机前瞻:三星/京东方柔性屏耐久性测试进展
  • 2025年世界职业院校技能大赛:项目简介模板
  • 工业一体机5G通讯IC/ID刷卡让MES系统管理更智能
  • SpringBoot 实现在线查看内存对象拓扑图 —— 给 JVM 装上“透视眼”
  • PostgreSQL + TimescaleDB 数据库语法配置
  • C++状态模式详解:从OpenBMC源码看架构、原理与应用
  • linux 下第三方库编译及交叉编译——MDBTOOLS--arm-64
  • uni-app 小程序跳转小程序
  • 《多级缓存架构设计与实现全解析》
  • Canon PowerShot D30相机 CHDK 固件 V1.4.1
  • 将 pdf 转为高清 jpg
  • uni-app实战教程 从0到1开发 画图软件 (橡皮擦)
  • PDF压缩原理详解:如何在不失真的前提下减小文件体积?
  • 高分辨率PDF压缩技巧:保留可读性的最小体积方案
  • 深入理解 RAG:检索增强生成技术详解
  • Hadoop面试题及详细答案 110题 (01-15)-- 基础概念与架构
  • gitlab仓库如何进行多人协作
  • 无人机探测器技术解析
  • GITLAB的Personal Access Tokens 和Project Access Tokens有什么区别