Master java skills

Equals and HashCode Contract

We know, HashMap stores unique keys. There is no problem as long as we use objects of java api’s predefined classes like String, Integer as keys. The problem arises when we use custom java objects like Employee as keys in HashMap. The problem arises with uniqueness of these custom objects.

Let’s try to understand using this example. In case of String objects, java knows that it will consider two String objects equal if their contents are same. But it doesn’t know when two employee objects will be considered equal. Will it consider only if only id and name of the employees are same or all the properties defined for employee should be exactly same? It demands the definition of equality from the writer of the Employee class.

There should be a way to determine when two custom objects will be considered equal. There comes into picture the combination of two methods : equals() and hashCode() from Object class. Until, we override these two methods and give the logic for equality of two objects, hash map is not going to guarantee unique keys and 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

1. The first point of the contract is that if you override equals() method, you must override hashCode().

2. If two objects are equal using the equals() method, then they must return the same hash code value using the hashCode() method.

3. 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.

4. 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

  1. Always use same attributes of an object to generate hashCode() and equals() both.
  2. equals() must be consistent (if the objects are not modified, then it must keep returning the same value).
  3. Whenever a.equals(b), then a.hashCode() must be same as b.hashCode().
  4. If you override one, then you should override the other.