重写equals和hashcode的正确方法是什么,其中两个变量中的任何一个都可以相等?

ale*_*lov 2 java equals hashcode

可以说我有以下课程

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;
    }

}
Run Code Online (Sandbox Code Playgroud)

是否有可能以保持equals和hashcode合约的方式覆盖hashcode?

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

Joh*_*ica 6

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

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

  • 它是自反的:对于任何非空引用值x,x.equals(x)应该返回true.
  • 它是对称的:对于任何非空引用值xy,x.equals(y)应该返回true当且仅当y.equals(x)回报true.
  • 它是传递性:对于任何非空的参考值x,y以及z,如果x.equals(y)回报率truey.equals(z)回报率true,那么x.equals(z)应该返回true.
  • 它是一致的:对于任何非空引用值x以及一致返回或一致返回的y多次调用,前提是不修改在对象比较中使用的信息.x.equals(y)truefalseequals
  • 对于任何非空引用值x,x.equals(null)应返回false.

具体来说,它不是传递性的.随着你的定义,(1,2) == (2,3)(2,3) == (3,4)而是(1,2) != (3,4).

这种非传递性使得无法实现非平凡的哈希码方法.您唯一能做的就是为每个对象返回相同的数字.这是一个有效的实现,虽然表现很差.