前言
在探究hashmap原理中计算数组位置一部分遇到了用h&(length-1)来替代h%length的问题,不解前者的原理,所以探究了一下。以下摘自文心一言。
正文
在表达式 return h & (length-1) 中,h 是一个哈希值(通常是一个较大的整数),而 length-1 是一个掩码(mask),用于将 h 限制在 0 到 length-1 的范围内。这个表达式是位运算中的一个常见技巧,用于快速地将一个整数映射到一个固定大小的数组或列表的索引。
为了理解这个表达式如何工作,让我们再次考虑 h 和 length-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 | 10101010 (h) |
在这个例子中,只有 h 的最低三位与 length-1 的相应位相匹配,因此结果是 00000010,即十进制中的 2。这个值现在可以用作数组或列表的索引,因为它已经被限制在 0 到 length-1(即 0 到 7)的范围内。
这种技术的一个关键前提是 length 必须是2的幂。如果 length 不是2的幂,那么 length-1 的二进制表示将不会有一系列连续的1,这可能导致哈希冲突或索引超出数组边界。当 length 是2的幂时,length-1 的二进制表示将有一系列连续的1,这可以确保 h 的任何位模式都会被映射到一个有效的索引。

