【问题标题】:What is the proper way of overriding equals and hashcode where either of two variables can be equal?在两个变量中的任何一个可以相等的情况下,覆盖等于和哈希码的正确方法是什么?
【发布时间】:2016-09-09 02:14:11
【问题描述】:

假设我有以下课程

public class DualKey {
    int key1;
    int key2;
    // getters, setters and constructors go here
    public void equals(Object obj) {
        if (obj == null || ! obj instanceOf DualKey)
            return false;
        return this.key1 == obj.key1 || this.key1 == obj.key2 || this.key2 == obj.key1 || this.key2 == obj.key2;
    }

}

是否可以以保留 equals 和 hashcode 合约的方式覆盖 hashcode?​​p>

PS:我意识到定义一个比较器可能会更好,但我正在使用 spark,其中定义相等的唯一方法是覆盖 equals 方法。

【问题讨论】:

  • 不,根据您的实际设置,这是不可能的(除非您只返回 0 这将保留合同“如果相等,则哈希码也必须相等”但您会有大量的冲突)

标签: java equals hashcode


【解决方案1】:

不,这是不可能的,因为 equals() 实现不符合 Java API 要求:

equals 方法在非空对象引用上实现等价关系:

  • 它是自反的:对于任何非空引用值xx.equals(x) 应该返回true
  • 它是对称的:对于任何非空引用值xy,当且仅当y.equals(x) 返回truex.equals(y) 应该返回true
  • 它是可传递的:对于任何非空引用值xyz,如果x.equals(y) 返回true 并且y.equals(z) 返回true ,然后x.equals(z) 应该返回true
  • 一致:对于任何非空引用值 xyx.equals(y) 的多次调用始终返回 true 或始终返回 false,未提供任何信息修改了用于equals 对象比较的对象。
  • 对于任何非空引用值xx.equals(null) 应返回false

具体来说,它不是传递的。根据您的定义,(1,2) == (2,3)(2,3) == (3,4)(1,2) != (3,4)

这种非传递性使得实现非平凡的哈希码方法成为不可能。您唯一能做的就是为每个对象返回相同的数字。这将是一个有效的实现,尽管性能很差。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-01
    • 2022-01-14
    • 1970-01-01
    • 2010-12-18
    • 1970-01-01
    相关资源
    最近更新 更多