I understand why providing same hashcode for two equal (through equals
) objects is important. But is the vice versa true as well, if two objects have same hash
If two objects have the same hashcode
then they are NOT necessarily equal. Otherwise you will have discovered the perfect hash function.
But the opposite is true: if the objects are equal, then they must have the same hashcode
.
hashcode() returns a unique integer ID for each object. If an object’s hashcode is not the same as another object’s hashcode, there is no reason to execute the equals() method: you just know the two objects are not the same. On the other hand, if the hashcode is the same, then you must execute the equals() method to determine whether the values and fields are the same.
Hash code method returns integer. If range of integer finishes then also two different object will have same hash code. So it is not necessary that two different object will have same hash code are equal.
According to the Javadoc in: http://download.oracle.com/javase/6/docs/api/java/lang/Object.html#hashCode%28%29
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.
Edit: In the real world two Strings may have the same hash code. For instance, if you want to store all string combinations that contain lowercase English letters (like "aaaaaaaaaa","aaaaaaaaab" and so on) of length 10, you can't assign a unique hash code to each of the 141.167.095.653.376 combinations, since int in Java is 32-bit and, therefore, can have up to 4.294.967.296 distinct values.
To prove , if two objects have the same hashCode does not mean that they are equal
Say you have two user defined classes
class Object1{
private final int hashCode = 21;
public int hashCode(){
return hashCode;
}
public boolean equals(Object obj) {
return (this == obj);
}
}
class Object2{
private final int hashCode = 21;
public int hashCode(){
return hashCode;
}
public boolean equals(Object obj) {
return (this == obj);
}
}
Object1 object1 = new Object1();
Object2 object2 = new Object2();
Object1 object3 = new Object1();
if(object1.hashCode() == object2.hashCode()){
// return true, because the hashcodes are same
}
but
if(object1.equals(object3)){
// will fail, because two different objects
}
Curiously, NumberFormat is an example of a Java foundation class which violates the recommendation that:
As much as is reasonably practical, the hashCode method defined by class Object does return distinct integers for distinct objects.
Here is some code showing this, at least under the version of Java I'm currently running under Mac OS X 10.6.
Numberformat nf = NumberFormat.getNumberInstance();
NumberFormat nf2 = NumberFormat.getNumberInstance();
assert nf != nf2; // passes -- they are different objects
assert !nf.equals(nf2); // passes -- they are not equal
assert nf.hashCode() != nf2.hashCode(); // fails -- same hash code