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

为什么hash%length 和hashlength-1 的值是一样的(当length=2的幂次方)

当 length 是 2 的幂次方时,hash % length 和 hash & (length - 1) 确实等价,这是计算机科学中一个巧妙的位运算优化。下面通过 4 个关键点彻底解释这个原理:


1. 数学本质(核心原理)

当 length = 2ⁿ 时:

  • length - 1 的二进制形式是 全1的比特位
    例如:length = 16 (2⁴) → length - 1 = 15 → 二进制 1111

  • hash & (length - 1) 相当于 保留hash的低n位,其他位归零
    这本质上就是 hash % length 的余数


2. 实例演示

假设 length = 8(2³):

length     = 8 = 00001000
length - 1 = 7 = 00000111  // 低3位全1

hash = 21  → 二进制 00010101
21 % 8 = 5
21 & 7 = 00010101 
        & 00000111
        ---------
          00000101 = 5  // 结果相同

3. 为什么等价?

  • 取模运算hash % length 求的是 hash 除以 length 的余数

  • 位与运算:当 length 是2的幂次方时,length - 1 的二进制形式是 00...011...1(低位全1)
    hash & (length - 1) 相当于:

    • 保留 hash 的低 log₂(length) 位

    • 丢弃高位(正好是 length 的整数倍部分)


4. 优势对比

运算性能适用场景注意事项
hash % length较慢任意length负数需额外处理(Math.abs)
hash & (length-1)极快length必须为2的幂次方自动处理负数(直接截取低位)

关键结论

  1. 等价条件:仅当 length 是 2 的幂次方时成立

  2. 性能差异:位运算比取模快 5-10 倍(CPU指令级优化)

  3. HashMap的设计
    JDK 中 HashMap 强制容量为2的幂次方(通过 tableSizeFor() 方法保证),就是为了使用这个优化技巧


为什么HashMap要用这个技巧?

  1. 极致性能:位运算是CPU原生支持的最快操作之一

  2. 避免负数问题& 运算天然处理负数的hash值(而 % 需要额外处理)

  3. 与扩容机制完美配合
    扩容时只需 newIndex = oldIndex | newCapacity(不需要重新计算hash)

理解这个原理,就掌握了HashMap性能优化的第一个关键设计!

相关文章:

  • Java:三十年演进,永续创新的编程传奇
  • 【SPP】蓝牙 SDP 协议在SPP中的互操作性解析
  • vue2修改窗口字典回显
  • 四款高效数据报表工具 让数据分析更简单
  • TCP的连接建立
  • 解释一下Unity碰撞的触发条件
  • 【LeetCode Solutions】LeetCode 121 ~ 125 题解
  • Unity中根据文字数量自适应长宽的对话气泡框UI 会自动换行
  • 助力 Windows 文件管理:重命名与清理重复文件软件精选
  • leetcode刷题日记——罗马数字转整数
  • 基于SpringBoot + HTML 的心理健康管理系统
  • PHY——LAN8720A 代码解析 (三)
  • HttpClient-01.介绍
  • Libevent UDP开发指南
  • 基于动态渲染与反检测技术的爬虫框架设计
  • Spring笔记05-面向切面编程
  • 每日一题(小白)暴力娱乐篇9
  • 【AI4CODE】4 Trae 锤一个数据搬运工的小应用
  • fpga:分秒计时器
  • 创建虚拟机
  • 总导演揭秘十五运会闭幕式:赴一场星辰大海之约
  • 人民日报整版调查:中小学春秋假,如何放得好推得开?
  • 复旦大学文科杰出教授裘锡圭逝世,享年90岁
  • 光大华夏:近代中国私立大学遥不可及的梦想
  • 上海充电桩调研:须全盘考量、分步实现车网互动规模化
  • 司法部:建立行政执法监督企业联系点,推行行政执法监督员制度