sp00m
sp00m

Reputation: 48807

Does it matter if two hashCodes are equal, even if the two objects aren't from the same type?

Let's say I have two types A and B that both have a unique id field, here is how I usually implement the equals() and hashCode() methods:

@Override
public boolean equals(Object obj) {
    return obj instanceof ThisType && obj.hashCode() == hashCode();
}

@Override
public int hashCode() {
    return Arrays.hashCode(new Object[] { id });
}

In that case, given that A and B both have a 1-arg constructor to set their respective id field,

new A(1).equals(new A(1)) // prints true as expected,
new A(1).equals(new A(2)) // prints false as expected,
new A(1).equals(new B(1)) // prints false as expected.

But also,

new A(1).hashCode() == new B(1).hashCode() // prints true.

I wonder if it matters if two hashCodes are equal, even if the two objects aren't from the same type? Could hashCode() be used somewhere else than in equals()? If yes, to what purpose?


I thought about implementing the two methods as follow:

@Override
public boolean equals(Object obj) {
    return obj != null && obj.hashCode() == hashCode();
}

@Override
public int hashCode() {
    return Arrays.hashCode(new Object[] { getClass(), id });
}

Adding the class to the hashCode generation would solve this potential problem. What do you think? Is it necessary?

Upvotes: 1

Views: 1329

Answers (6)

Ingo
Ingo

Reputation: 36329

Not that, when A extends B, or B extends A, then your equals method is faulty, since:

a.equals(b) != b.equals(a)

if a and b happen to have the same hash code.

Upvotes: 0

UmNyobe
UmNyobe

Reputation: 22890

The rule is simple:

  • A.equals(B) implies B.hashcode() == A.hashcode()
  • B.hashcode() != A.hashcode() implies !A.equals(B)

There should be no other relations between the two. If you use hashcode() inside equals(), you should have a warning.

Upvotes: 1

Bhavik Shah
Bhavik Shah

Reputation: 5183

Could hashCode() be used somewhere else than in equals()?

This method is supported for the benefit of hashtables such as those provided by java.util.Hashtable. from javadoc

Also

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result. It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.
  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hashtables.

Upvotes: 0

Mikhail Vladimirov
Mikhail Vladimirov

Reputation: 13890

Nothing wrong with two different objects (even of the same type) to have the equal hash code, but your second variant of equals() looks odd to me. It will work only if you can guarantee that your objects will be compared only to the objects of the same type.

Upvotes: 0

Marko Topolnik
Marko Topolnik

Reputation: 200138

Hashcode is definitely not used in equals; it is used by collections based on the data structure called a hash table. It is always OK from the correctness standpoint for two hashcodes to equal each other; this is called a hash collision, it is unavoidable in the general case, and the only consequence is weaker performance.

Upvotes: 0

Uwe Plonus
Uwe Plonus

Reputation: 9954

For objects of different classes the same hashCode() does not matter. The hashCode() only says that the objects are possibly the same. If e.g. HashSet encounters the same hashCode() it will test for equality with equals().

Upvotes: 2

Related Questions