首页 > 解决方案 > 除了 Collections API,在 Java 中覆盖 hashCode 有什么用?

问题描述

面试官问这个问题,大多数与哈希码相关的答案都用于分桶,它检查等于搜索对象。

是否有任何其他一般用例或场景,其中哈希码是有益的并且可以在常规程序中使用?

最近我使用了JPA,它抛出异常"Composite-id class does not override hashCode()",但它再次被hibernate的实现类使用。Sly,除了集合之外,我们还可以在哪些其他地方或场景中使用哈希码,尤其是您自己使用过的场景。

class a {
    public int hashCode() {
    }
}

class b {
    public static void main(String[] str) {
        //In what ways can i use hashcode here?
    }
}

标签: javahashmaphashcodehash-code-uniqueness

解决方案


假设您的类永远不会在任何集合中使用(尽管这不太可能),它将在多个地方和其他开发人员使用。任何使用您的类的开发人员都会期望,如果该类的两个实例基于 equals 方法相等,则它们应该产生相同的 hashCode 值。如果 hashCode 没有被覆盖以与 equals 一致,那么这个基本假设将被打破,这将阻止它们的代码正常运行。

来自 Effective Java,第 3 版:

第 11 项:当您覆盖等于时,始终覆盖哈希码

您必须在每个覆盖 equals 的类中覆盖 hashCode。如果你不这样做,你的类将违反 hashCode 的一般约定,这将阻止它在 HashMap 和 HashSet 等集合中正常运行。这是合同,改编自对象规范:

• 当在应用程序执行期间对对象重复调用hashCode 方法时,它必须始终返回相同的值,前提是未修改equals 比较中使用的信息。该值不需要在应用程序的一次执行到另一次执行中保持一致。

• 如果两个对象根据equals(Object) 方法相等,那么对两个对象调用hashCode 必须产生相同的整数结果。

• 如果两个对象根据equals(Object) 方法不相等,则不需要对每个对象调用hashCode 必须产生不同的结果。但是,程序员应该意识到,为不相等的对象产生不同的结果可能会提高哈希表的性能。

当您未能覆盖 hashCode 时违反的关键规定是第二条:相等的对象必须具有相等的哈希码。根据类的 equals 方法,两个不同的实例可能在逻辑上相等,但对于 Object 的 hashCode 方法,它们只是两个没有太多共同点的对象。因此,Object 的 hashCode 方法返回两个看似随机的数字,而不是合约要求的两个相等的数字。


推荐阅读