需要解释有效Java教科书中的hashcode示例吗

需要解释有效Java教科书中的hashcode示例吗,java,hashcode,effective-java,Java,Hashcode,Effective Java,以下是第9项中的示例代码: public final class PhoneNumber { private final short areaCode; private final short prefix; private final short lineNumber; @Override public int hashCode() { int result = 17; result = 31 * result + areaCode; result

以下是第9项中的示例代码:

public final class PhoneNumber {
  private final short areaCode;
  private final short prefix;
  private final short lineNumber;

  @Override
  public int hashCode() {
    int result = 17;
    result = 31 * result + areaCode;
    result = 31 * result + prefix;
    result = 31 * result + lineNumber;
    return result;
  }
}
第48页指出:“之所以选择值31,是因为它是一个奇素数。如果它是偶数且乘法溢出,则信息将丢失,因为乘以2等于移位。”


我理解乘2等于位移位的概念。我还知道,当我们将一个大的数字乘以一个大的奇数素数时,仍然会出现溢出(因此信息丢失)。我不明白的是,为什么由大奇数素数相乘产生的信息损失比由大偶数相乘产生的信息损失更可取。

没有大偶数素数这样的东西——唯一的偶数素数是2

撇开这一点不谈——使用中等大小的素数而不是像3或5这样的小素数的一般要点是尽量减少两个对象以相同的哈希值结束的可能性,不管是否溢出


溢出风险本身不是问题;真正的问题是哈希代码值对于被哈希的对象集的分布情况。由于hashcode用于HashSet、HashMap等数据结构中,因此您希望最小化可能共享相同hash code的对象的数量,以优化这些集合上的查找时间。

对于偶数乘法器,乘法后的最低有效位始终为零。使用奇数乘法器时,最低有效位为1或0,具体取决于
result
之前的值。因此,偶数乘法器正在丢失低位的不确定性,而奇数乘法器正在保留低位。

除了2,没有其他偶数是primeomg!真不敢相信我竟然忘了这个。我想我今天有点傻。谢谢:)这可能是一个副本。