可能重复:
为什么 Java 的 String 中的 hashCode() 使用 31 作为乘数?
为什么在 hashCode 中使用素数?
来自Effective Java Item 9: Always override hashCode when you override equals考虑以下相关代码片段,它覆盖了 Object 类中定义的 hashcode()。
public final class PhoneNumber {
private final short areaCode;
private final short prefix;
private final short lineNumber;
......//Rest ignored on purpose
.....
private volatile int hashCode; // (See Item 71)
@Override public int hashCode() {
int result = hashCode;
if (result == 0) {
result = 17;
result = 31 * result + areaCode;
result = 31 * result + prefix;
result = 31 * result + lineNumber;
hashCode = result;
}
return result;
}
}
我明白为什么选择非零初始值“17”。我也理解乘法是在每个步骤中完成的,因此字段的顺序在计算中起着重要作用hashcode()
。但我不明白选择 31 作为乘法值的原因。有人可以向我解释为什么吗?这就是布洛赫要说的关于 31 的内容,但我真的不明白。我特别无法理解下面斜体字。
选择值 31 是因为它是一个奇数素数。如果它是偶数并且乘法溢出,信息将会丢失,因为乘以 2 相当于移位。使用素数的优势不太明显,但它是传统的。