java - 在两个变量中的任何一个可以相等的情况下,重写 equals 和 hashcode 的正确方法是什么?

标签 java equals hashcode

假设我有以下类(class)

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?

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

最佳答案

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

The equals method implements an equivalence relation on non-null object references:

  • It is reflexive: for any non-null reference value x, x.equals(x) should return true.
  • It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
  • It is transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true.
  • It is consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
  • For any non-null reference value x, x.equals(null) should return false.

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

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

关于java - 在两个变量中的任何一个可以相等的情况下,重写 equals 和 hashcode 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39402812/

相关文章:

java - 获取 hashmap 中的等价元素

java - 为什么我们需要在 java 中覆盖 equals 和 hashcode,为什么我们不能使用 Object 类实现

java - hashCode 在 Java 中如何工作

java - 如何在 Objective-C 中获得与 Java String.hashCode() 相同的结果?

java - 从 html 到 servlet

java - 带有日期作为 x 标签的 JFreeChart

java - 声明实例变量并实现 getter 方法?

java - Kotlin 对象类实例 get()

java - 为什么 Java 的 Area#equals 方法不覆盖 Object#equals?

java - 最终类是否必须重写 equals() 和 hashCode() 方法