I need some help in better understanding hashCode()
method in a theoretical way. I´ve read (emphasis mine):
When
hashCode()
is called on two separate objects (which are equal according to theequals()
method) it returns the same hash code value. However, if it is called on two unequal objects, it will not necessarily return different integer values.
Where can said exceptions occur?
Suppose you have a class with two String fields, and that its hashcode is calculated by summing the hashcodes of those two fields. Further suppose you have an equals that simply checks whether the class fields values are equal.
class Test {
String a;
String b;
public Test
@Override
public int hashCode() {
return a.hashCode() + b.hashCode();
}
@Override
public boolean equals(Object o) { // simplified
Test other = (Test)o;
return a.equals(other.a) && b.equals(other.b);
}
}
Let's see if non-equal instances can have the same hashcode
Test t1 = new Test("hello", "world");
Test t2 = new Test("world", "hello");
System.out.println(t1.equals(t2)); // false
System.out.println(t1.hashCode() == t2.hashCode()); // true
Are we still respecting hashCode
's contract?
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.
Well, yes, since it only depends on a
and b
and we're using their hashCode
method which we can assume respects the contract.
If two objects are equal according to the
equals(Object)
method, then calling thehashCode
method on each of the two objects must produce the same integer result.
It does
Test t1 = new Test("hello", "world");
Test t2 = new Test("hello", "world");
System.out.println(t1.equals(t2)); // true
System.out.println(t1.hashCode() == t2.hashCode()); // true
It is not required that if two objects are unequal according to the
equals(java.lang.Object)
method, then calling thehashCode
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 hash tables.
That's what we were trying to demonstrate in the first place. It's not a requirement.