3

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

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

最近我使用了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?
    }
}
4

3 回答 3

2

假设您的类永远不会在任何集合中使用(尽管这不太可能),它将在多个地方和其他开发人员使用。任何使用您的类的开发人员都会期望,如果该类的两个实例基于 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 方法返回两个看似随机的数字,而不是合约要求的两个相等的数字。

于 2019-12-24T08:15:53.333 回答
1

面试问题中的一个小语义错误。哈希码不用于检查相等性,它用于检测不等式。如果哈希码不同,则保证对象不相等。如果代码相等,则对象可能相等,需要使用 equals 方法检查。

也就是说,如果哈希码被缓存,它可以用来加速 equals 方法。

于 2019-12-24T06:17:47.527 回答
1
  • 假设您只覆盖 equals 而不是 hashCode
  • 这意味着 hashCode 继承自 Object
  • Object.hashCode 总是尝试为不同的对象返回不同的哈希码(不管它们是否相等)
  • 这意味着对于您认为相等的两个对象,您最终可能会得到不同的哈希码。
  • 这反过来又导致这两个相等的对象最终在基于哈希的集合(如 HashSet)中的不同存储桶中。
  • 这会导致此类集合中断。

更多参考:https ://programming.guide/java/overriding-hashcode-and-equals.html

于 2019-12-24T06:21:42.413 回答