0%

关于h&(length-1)的探究


前言

在探究hashmap原理中计算数组位置一部分遇到了用h&(length-1)来替代h%length的问题,不解前者的原理,所以探究了一下。以下摘自文心一言。

正文

在表达式 return h & (length-1) 中,h 是一个哈希值(通常是一个较大的整数),而 length-1 是一个掩码(mask),用于将 h 限制在 0length-1 的范围内。这个表达式是位运算中的一个常见技巧,用于快速地将一个整数映射到一个固定大小的数组或列表的索引。

为了理解这个表达式如何工作,让我们再次考虑 hlength-1 的二进制表示。假设 length 是一个2的幂,例如 length = 2^n,那么 length-1 就是 2^n - 1。这个数在二进制中表示为 n 个1,从最低位到第 n 位。

例如,如果 length = 8(即 2^3),则 length-1 = 7,其二进制表示为 0111(假设我们在一个足够大的位数中考虑,比如8位,则为 00000111)。

现在,假设 h 是一个任意的哈希值,其二进制表示可能看起来像这样(以8位为例):

1
h = 10101010

当我们执行 h & (length-1) 时,我们实际上是在执行以下按位与操作:

1
2
3
4
10101010 (h)  
& 00000111 (length-1)
----------
00000010 (result)

在这个例子中,只有 h 的最低三位与 length-1 的相应位相匹配,因此结果是 00000010,即十进制中的 2。这个值现在可以用作数组或列表的索引,因为它已经被限制在 0length-1(即 07)的范围内。

这种技术的一个关键前提是 length 必须是2的幂。如果 length 不是2的幂,那么 length-1 的二进制表示将不会有一系列连续的1,这可能导致哈希冲突或索引超出数组边界。当 length 是2的幂时,length-1 的二进制表示将有一系列连续的1,这可以确保 h 的任何位模式都会被映射到一个有效的索引。

学习地址

HashMap终极总结,Java7与Java8的区别_java7 和java8 hashmap的区别-CSDN博客