Reputation: 3121
Lets say I have the following 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;
}
}
Is it possible to override hashcode in such a way that the equals and hashcode contract is preserved?
PS: I realize that it would probably be better to define a comparator instead, but I'm working with spark, where the only way to define equality is to override the equals method.
Upvotes: 2
Views: 133
Reputation: 361585
No, it is not possible, because that equals()
implementation does not meet the Java API requirements:
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
.
Specifically, it is not transitive. With your definition, (1,2) == (2,3)
and (2,3) == (3,4)
but (1,2) != (3,4)
.
This non-transitivity makes it impossible to implement a non-trivial hash code method. The only thing you can do is return the same number for every object. That'd be a valid implementation, though very poorly performing.
Upvotes: 6