Reputation: 48807
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
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
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
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:
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
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
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
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