Why do we need to Override equals and hashcode methods in Java

In this post, we will discuss why it is important to override equals and hashCode method in Java.


 

Item 9 in Josh Bloch’s Effective Java suggests to always override hashCode() method if the class overrides equals(). In this post, we will discuss why this is necessary and a good practice.

 
We know that two objects are considered equal only if their references points to the same object and unless we override equals() and hashCode() methods, the class object will not behave properly on hash-based collections like HashMap, HashSet, and Hashtable. This is because hash-based collections are organized like a sequence of buckets, and the hash code value of an object is used to determine the bucket where the object would be stored, and the same hash code is used again to find the object’s position in the bucket. The key retrieval is basically a two-step process:

  1. Finding the correct bucket using hashCode() method.
     
  2. Linearly searching the bucket for the key using equals() method.

Now let’s take an example to demonstrate the need for overriding equals and hashCode method in Java:

 

Download   Run Code

Output:

[{John, 80000}]

 
As evident from the generated output, the set contains only one Employee object even though two different Employee objects are added to it. This is because we have overridden both equals() and hashCode() method in the Employee class and both objects now points to the same bucket and also holds the same location within the bucket.

 
Now let’s discuss the behavior of above program if equals() method is overridden without overriding hashCode() or vice versa.

 

1. Override only equals() without overriding hashCode()

Overriding only equals() method without overriding hashCode() causes the two equal instances to have unequal hash codes, that is in violation of the hashCode contract (mentioned in Javadoc) that clearly says, 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.

 
Since the default hashCode implementation in the Object class return distinct integers for distinct objects, if only equals() method is overridden, e1 will be placed in some bucket and e2 will be placed in some other bucket as e1.hashCode() != e1.hashCode(). So even though both e1 and e2 are equal, they don’t hash to the same bucket and both of them reside in the collection as separate keys.

It is worth noting that if the class instance is never used in any hash-based collections, then it doesn’t really matter if hashCode() is overridden or not.

 

2. Override only hashCode() without overriding equals()

If we only override hashCode() method, both e1 and e2 will hash to the same bucket as they produces the same hash code. But since equals() method is not overridden, when the set hashes e2 and iterates through the bucket looking if there is an Employee e such that e2.equals(e) is true, it won’t find any as e2.equals(e1) will be false.

Please note that even though equal objects must have equal hash codes, the reverse is not true. It is perfectly valid to override hashCode() without overriding equals() as objects with equal hash codes need not be equal.

 
References: StackOverflow

 
Thanks for reading.




Please use ideone or C++ Shell or any other online compiler link to post code in comments.
Like us? Please spread the word and help us grow. Happy coding 🙂
 





Leave a Reply

Notify of
avatar
wpDiscuz