假设我有以下课程
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 :(得分:6)
不,这是不可能的,因为equals()
实现不符合Java API要求:
equals方法在非null对象引用上实现等价关系:
- reflexive :对于任何非空参考值
x
,x.equals(x)
应返回true
。- 对称:对于任何非空引用值
x
和y
,x.equals(y)
应返回true
当且仅当{ {1}}返回y.equals(x)
。- 传递:对于任何非空引用值
true
,x
和y
,如果z
返回{{1} }和x.equals(y)
返回true
,然后y.equals(z)
应该返回true
。- 一致:对于任何非空引用值
x.equals(z)
和true
,x
的多次调用始终返回y
或始终如一返回x.equals(y)
,前提是没有修改对象true
比较中使用的信息。- 对于任何非空引用值
false
,equals
应返回x
。
具体而言,它不具有传递性。根据您的定义,x.equals(null)
和false
,但(1,2) == (2,3)
。
这种非传递性使得无法实现非平凡的哈希码方法。您唯一能做的就是为每个对象返回相同的数字。这是一个有效的实施,但表现很差。