Understanding equals and hashcode

The equals() and hashCode() are two primary methods of Java’s Object Class which every Java developer must be aware of. These methods work together to help uniquely identify any object in Java. These methods are majorly used by the Java Collection classes that are based on the principle of hash function, to check uniqueness of the objects stored in these collections.

Signatures of hashCode() and equals()

public boolean equals(Object obj)
public int hashCode()

General contract between equals() and hashCode() in Java

  • If two objects are equal by equals() method, then their hashCode() method must return the same value.
  • If two objects are not equal by equals() method, then their hashCode() method need not return different values. The hashcode() method may return same or different value.
  • The hashCode() method must return same value on multiple invocation on the same object, within a single execution of the application, provided the fields used in equals() and hashCode() have not been modified.

Overriding equals() and hashCode() in Java

Let's consider the simple Employee class below:

public class Employee {
    private int id;
    private String name;
    private String designation;
    private int salary;    
}

Overriding equals()

To override the equals method, we need to identify the fields that we need to check for equality. Considering the fact that an employee's name and his id are not supposed to change we can safely assume that two objects having same name and id are equal. Hence, we can use id and name field in the equals method as shown below:

public boolean equals(Object obj) {
    
    if(obj == null)
        return false;
    if(!(obj instanceof Employee))
        return false;
    
    Employee emp = (Employee) obj;
    if(this.name == emp.name && this.id == emp.id)
        return true;
    else
        return false;
}

Overriding hashCode()

While overriding hashCode() method, we need to obey the contract we stated earlier. We need to ensure that the object considered as equal must return the same hashCode value.

We can follow the below steps to override the hashCode() method:

  • Take a prime number
  • Take another prime and multiply it to the hashCode of each field used in equals() method
  • Multiply zero if the field is null
  • Add the hash values of each field and return the final hash value

Shown below is our implementaion of hashCode() method:

public int hashCode() {
    int hashValue = 3;
    hashValue = hashValue + (7 * (this.id));
    hashValue = hashValue + (7 * (this.name == null ? 0 : this.name.hashCode()));
    return hashValue;
}

When should we override hashcode() and equals()?

We should override hashCode() and equals() in all classes that are supposed to work in conjunction with any hash-based collection. Failing to do so will produce unexpected results.

RELATED ARTICLES

Internal Implementation of ArrayList

ArrayList is an implementation of List interface, used to store a list of objects. Unlike normal arrays, it is a dynamic data structure, its size dynamically increases when its capacity is exhausted.

View Article

Internal Implementation of HashMap

HashMap is popular data structure in Java which stores data in key-value format. This article describes the internal implementation to store and retrieve data in a hashmap.

View Article

Internal Implementation of HashSet

HashSet is a member of the Java Collection Framework which is used to store unique entries. This article describes how a HashSet is internally implemented to store unique entries.

View Article

Identity HashMap in Java

IdentityHashMap in Java is a special implentation of the Map interface designed to be used in special cases where reference equality is required.

View Article

Iterator and ListIterator in Java

The Java API provides the Iterator and ListIterator that are used to iterate over a Collection. This article covers the difference between the two and discuss how Emumeration is different from Iterat.

View Article

Introduction to Java Collections

The Java collections framework is a library that provides commonly reusable collection data structures. It consists of a set of various interfaces, implementations and algorithms used to represent...

View Article

Understanding TreeMap

A TreeMap is an implementation of the Map interface used to store key-value pair in sorted order of their keys. This articles describe how a Treemap is implemented in Java.

View Article