alexgbelov
alexgbelov

Reputation: 3121

What is the proper way of overriding equals and hashcode where either of two variables can be equal?

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

Answers (1)

John Kugelman
John Kugelman

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 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.

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

Related Questions