【问题标题】:Does hashCode() have to return a prime number?hashCode() 是否必须返回素数?
【发布时间】:2010-04-22 07:59:34
【问题描述】:

hashCode() 方法的签名是

public int hashCode(){
    return x;
}

在这种情况下 x 必须是一个 int(primitive) 但请谁能向我解释一下这个数字 hashCode() 返回的必须是素数,偶数...等还是没有规范?我问这个问题的原因是我在不同的 id 中看到它自动生成的代码总是返回一个素数,所以我需要知道为什么?

提前致谢

【问题讨论】:

标签: java hashcode


【解决方案1】:

其实有一个关于hashCode()的合约非常明确:

返回对象的哈希码值。支持此方法是为了便于使用 java.util.Hashtable 提供的哈希表。 hashCode的总合约是:

  • 在 Java 应用程序执行期间,只要在同一对象上多次调用它,hashCode 方法必须始终返回相同的整数,前提是没有修改对象上相等比较中使用的信息。该整数不需要从应用程序的一次执行到同一应用程序的另一次执行保持一致。
  • 如果两个对象根据equals(Object) 方法相等,那么对两个对象中的每一个调用hashCode 方法必须产生相同的整数结果。
  • 如果两个对象根据equals(java.lang.Object) 方法不相等,则不要求对这两个对象中的每一个调用hashCode 方法必须产生不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同的整数结果可能会提高哈希表的性能。

在合理可行的情况下,Object 类定义的 hashCode 方法确实为不同的对象返回不同的整数。 (这通常通过将对象的内部地址转换为整数来实现,但 Java™ 编程语言不需要这种实现技术。)

Documentation for the java.lang.Object class

返回的内容由您自己决定,如果您想要,您可以为每个对象实例发出0。这可能是一个坏主意,但完全有效。它绝不总是一个质数。如文档中所述,默认实现只返回对象的内部地址——这与 equals 检查引用相等性的默认实现一致。

您通常可以通过在构成对象状态的字段上调用 ​​hashCode 方法来构造哈希,例如:

class Person {
    private String firstName;
    private String lastName;

    @Override
    public int hashCode() {
        return firstName.hashCode() + lastName.hashCode();
    }
}

请记住,只要您认为对象状态的表示发生变化,请同时更新 hashCodeequals

【讨论】:

    【解决方案2】:

    这是关于效率

    hashCode 不是必须的素数,即使 hashCode 也可以返回一个常量 int。 但是为了效率,质数导致性能好,而常量 hashCode 性能最差(哈希表恶化为列表)。

    【讨论】:

    • 它不是相对于哈希表的当前大小吗?我认为通常选择哈希表大小以使其更有可能。您的评论可能会让某人相信他们应该找到一个质数来编写他们的哈希码,这将是非常低效的。我认为,只要您生成分布良好的数字,您就不必担心太多。
    猜你喜欢
    • 1970-01-01
    • 2023-03-24
    • 1970-01-01
    • 2020-04-17
    • 2017-02-25
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    • 2019-12-15
    相关资源
    最近更新 更多