在两个变量中的任何一个可以相等的情况下,覆盖 equals 和 hashcode 的正确方法是什么?
What is the proper way of overriding equals and hashcode where either of two variables can be equal?
假设我有以下 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()
实现不符合JavaAPI要求:
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)
.
这种非传递性使得无法实现非平凡的哈希码方法。您唯一可以做的就是 return 每个对象的相同数字。那将是一个有效的实现,尽管性能很差。
假设我有以下 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()
实现不符合JavaAPI要求:
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 returntrue
.- It is symmetric: for any non-null reference values
x
andy
,x.equals(y)
should returntrue
if and only ify.equals(x)
returnstrue
.- It is transitive: for any non-null reference values
x
,y
, andz
, ifx.equals(y)
returnstrue
andy.equals(z)
returnstrue
, thenx.equals(z)
should returntrue
.- It is consistent: for any non-null reference values
x
andy
, multiple invocations ofx.equals(y)
consistently returntrue
or consistently returnfalse
, provided no information used inequals
comparisons on the objects is modified.- For any non-null reference value
x
,x.equals(null)
should returnfalse
.
具体来说,它是不可传递的。根据您的定义,(1,2) == (2,3)
和 (2,3) == (3,4)
但 (1,2) != (3,4)
.
这种非传递性使得无法实现非平凡的哈希码方法。您唯一可以做的就是 return 每个对象的相同数字。那将是一个有效的实现,尽管性能很差。