【问题标题】:Need explanation for hashcode example in Effective Java textbook需要解释 Effective Java 教科书中的哈希码示例
【发布时间】:2012-06-06 13:35:10
【问题描述】:

这是第 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;
  }
}

Pg 48 状态:“选择值 31 是因为它是一个奇素数。如果它是偶数并且乘法溢出,则信息将丢失,因为乘以 2 是等价的转移。”

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

【问题讨论】:

  • 除了 2,没有其他偶数是素数
  • 天哪!我不敢相信我忘记了这一点。我想我今天刚刚度过了一个愚蠢的时刻。谢谢:)
  • 这可能是 stackoverflow.com/questions/299304/… 的副本。

标签: java hashcode effective-java


【解决方案1】:

对于偶数乘法器,乘法后的最低有效位始终为零。对于奇数乘数,最低有效位为 1 或 0,具体取决于 result 的先前值。因此,偶数乘法器失去了低位的不确定性,而奇数乘法器保留了它。

【讨论】:

    【解决方案2】:

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

    除此之外 - 使用中等大小的素数 # 而不是像 3 或 5 这样的小素数的一般意义是最大限度地减少两个对象最终具有相同哈希值的可能性,无论是否溢出。

    溢出风险本身不是问题;真正的问题是散列对象集的散列码值将如何分布。由于哈希码用于 HashSet、HashMap 等数据结构中,因此您希望尽量减少可能共享相同哈希码的对象数量,以优化对这些集合的查找时间。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-01-15
      • 1970-01-01
      • 1970-01-01
      • 2017-07-12
      • 1970-01-01
      • 2015-09-15
      • 1970-01-01
      相关资源
      最近更新 更多