Equals and HashCode Contract
We know, hashmap stores unique keys. There is no problem as long as we use java api classes. The problem arises when we use custom java classes as keys in hashmap. The problem with uniqueness of the objects.
There should be a way to determine when two custom objects will be considered unique. That way is a combination of two methods : equals() and hashCode() methods from Object class. Until, we override these two methods and give the logic for equality of two objects, hash map is not going to work properly.
equals() and hashCode() methods works together. There is a contract between the two. Let’s understand it.
equals() method
equals() method is defined in Object class, but it can be overridden by every class. As name suggests, it is used to compare two objects for equality. Suppose, we have an employee class with 3 attributes : id, name, age. Now it is upto us what definition of equality for two employees we want to give. And we can do so by overridding equals() method.
As I mentioned, equals() method is part of Object class, it has a default definition too. As per its default definition, two objects are equal only and only if the reference variables are pointing to the exactly same object.
hashCode() method
hashCode() method is also defined in Object class, but it can also be overridden by every class. It is a unique integer value derived by using hashing technique. This hashcode is used to find the bucket location if the object is to be used as a key in a hash table like data structure.
equals() and hashCode() contract
- The first point of the contract is that if you override equals() method, you must override hashCode().
- If two objects are equal using the equals() method, then they must return the same hash code value using the hashCode() method.
- If two objects are not equal according to the equals() method, then it is not necessary that they must return the same hash code value. However, hashCode() method should be implemented in such a way that it should return different hashcode for unequal objects, so that the performance of the map is better.
- Whenever hashcode() is invoked on the same object more than once during an execution of a Java program, the hashCode() method must consistently return the same integer, given that no information used in equals() method on the object is modified. This integer need not remain consistent from one execution to another execution of the same application.
equals() and hashCode() best practices
- Always use same attributes of an object to generate hashCode() and equals() both.
- equals() must be consistent (if the objects are not modified, then it must keep returning the same value).
- Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().
- If you override one, then you should override the other.