第11题:为什么HashMap的数组长度必须是2的指数次幂
📚 回答:
-
核心原因:
HashMap的数组长度必须是2的指数次幂,是为了通过高效的位运算替代低效的取模运算来计算元素的存储位置下标。 -
背景知识:
- 当我们向
HashMap中添加元素时,需要根据key的哈希值计算出它在数组中的存储位置(即索引)。 - 理论上可以通过取模运算(
hash % length)来计算索引,但取模运算在计算机中效率较低。 HashMap采用了一种等价于取模运算的按位与运算((length - 1) & hash),前提是数组长度必须是2的指数次幂。
- 当我们向
-
为什么必须是2的幂?
- 如果数组长度是2的指数次幂(如16、32、64),那么
length - 1的二进制表示就是全1(如15的二进制是1111)。 - 此时,按位与运算
hash & (length - 1)的结果等价于取模运算hash % length,且效率更高。 - 如果数组长度不是2的幂(如10),按位与运算的结果将不等于取模运算结果,导致散列分布不均匀,增加冲突概率。
💡 代码示例:
以下代码展示了位运算与取模运算的关系: - 如果数组长度是2的指数次幂(如16、32、64),那么
int length = 16; // 数组长度为2的幂
int hash = 25; // 假设哈希值为25
// 取模运算
int index1 = hash % length; // 结果为9
// 按位与运算
int index2 = hash & (length - 1); // 结果同样为9
System.out.println(index1 == index2); // 输出 true
💡 面试官视角:
- 面试官可能会问“为什么位运算更高效?”答:位运算是直接操作二进制位,CPU执行速度快;而取模运算涉及除法操作,性能较差。
- 面试官可能会追问“如果数组长度不是2的幂会怎么样?”答:会导致散列分布不均,冲突概率增加,查询效率下降。