【问题标题】:What is the use of overriding hashCode in Java other than Collections API?除了 Collections API,在 Java 中覆盖 hashCode 有什么用?
【发布时间】:2020-04-15 06:48:42
【问题描述】:

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

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

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

【问题讨论】:

    标签: java hashmap hashcode hash-code-uniqueness


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:
      • 假设您只覆盖 equals 而不是 hashCode
      • 这意味着hashCode继承自Object
      • Object.hashCode 总是尝试为不同的对象返回不同的哈希码(不管它们是否相等)
      • 这意味着对于您认为相等的两个对象,您最终可能会得到不同的哈希码。
      • 这反过来又会导致这两个相等的对象最终位于基于哈希的集合(例如 HashSet)中的不同存储桶中。
      • 这会导致此类集合中断。

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

      【讨论】:

      • OP 的问题是 hashCode 在集合框架以外的地方使用。
      • 这是一个类似的问题:stackoverflow.com/questions/22646456/…
      • 您必须在每个覆盖 equals() 的类中覆盖 hashCode()。不这样做将导致违反 Object.hashCode() 的一般合同,这将阻止您的类与所有基于散列的集合一起正常运行。当实体没有复合 ID 时,它们只有一个,是基本支持的类型之一(Integer、Long、String 等),并且这些类已经有明确定义的 equals()(和 hashCode( )) 方法。
      【解决方案3】:

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

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

      【讨论】:

      • OP 提出的问题与您的答案无关。 hasCode 除了在集合框架中还有哪些用例。您的回答说明了如何使用 hashCode。对equals() 的调用通常不依赖于hashCode()(在集合和映射之外)。
      • @Prashant 你错了。问题是“是否有任何其他一般用例或场景,其中哈希码是有益的并且可以在常规程序中使用?”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-19
      • 2013-06-11
      • 2015-01-15
      • 2023-03-27
      相关资源
      最近更新 更多