有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

以下是第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) 个答案

  1. # 1 楼答案

    没有大的偶数素数——唯一的偶数素数是2

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

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

  2. # 2 楼答案

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