Why is it important to override the hashCode method when you override equals? What would be the consequence if we don’t?

When a class overrides equals(), it should also override hashCode() to maintain the contract between these two methods. Hash-based collections such as HashMap, HashSet, and Hashtable rely on both methods to store, search, and retrieve objects correctly. If only equals() is overridden, logically equal objects may be treated as different objects, leading to unexpected behavior.

Key Points: • hashCode() and equals() must be consistent with each other. • Equal objects must always produce the same hash code. • Hash-based collections use hashCode() first and equals() second. • Failing to override hashCode() can cause duplicate entries and failed lookups. • Overriding both methods is a best practice for custom classes.

Why Are Both Methods Needed?

hashCode():

• Determines the bucket where an object is stored. • Improves search performance.

equals():

• Verifies whether two objects are logically equal. • Resolves collisions within the same bucket.

How Hash-Based Collections Work:

When an object is inserted into a HashSet or HashMap:

1. hashCode() determines the bucket location. 2. equals() checks whether an equivalent object already exists. 3. If both methods agree, duplicates are prevented.

Example: Suppose two Employee objects have the same ID.

Employee emp1 = new Employee(101);

Employee emp2 = new Employee(101);

Logically, these objects should be considered equal.

If equals() is overridden but hashCode() is not, both objects may generate different hash codes and be stored in different buckets.

Result:

• Duplicate objects may appear in a HashSet. • HashMap searches may fail unexpectedly.

Code Example:

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

class Employee {

    private int id;

    Employee(int id) {
        this.id = id;
    }

    @Override
    public boolean equals(Object obj) {

        if (this == obj) {
            return true;
        }

        if (!(obj instanceof Employee)) {
            return false;
        }

        Employee emp = (Employee) obj;

        return this.id == emp.id;
    }

    @Override
    public int hashCode() {

        return Objects.hash(id);
    }
}

public class Demo {

    public static void main(String[] args) {

        Set<Employee> employees =
                new HashSet<>();

        employees.add(new Employee(101));
        employees.add(new Employee(101));

        System.out.println(employees.size());
    }
}

Output:

1

Because both equals() and hashCode() are overridden correctly, HashSet recognizes the second object as a duplicate.

What Happens If hashCode() Is Not Overridden?

Problems:

• Duplicate objects may be stored in HashSet. • HashMap.get() may fail to find an existing key. • Collection behavior becomes inconsistent. • Performance may degrade due to improper bucket distribution.

Example Scenario:

HashMap<Employee, String> map =
        new HashMap<>();

map.put(new Employee(101), "John");

Later:

map.get(new Employee(101));

Expected:

John

Possible Result:

null

This happens because the lookup object may be placed in a different bucket due to a different hash code.

hashCode() and equals() Contract:

1. If two objects are equal according to equals(), they must return the same hashCode(). 2. If two objects have the same hashCode(), they are not necessarily equal. 3. Unequal objects may have different hash codes.

Real-World Example:

Consider a banking application where Account objects are stored in a HashSet.

If hashCode() is not overridden properly:

• Duplicate accounts may be stored. • Account searches may fail. • Data integrity issues can occur.

Interview Tip: A concise interview answer is:

"When equals() is overridden, hashCode() must also be overridden because hash-based collections use hashCode() to locate objects and equals() to verify equality. If hashCode() is not overridden, logically equal objects may be stored in different buckets, causing duplicate entries, failed lookups, and inconsistent behavior in collections such as HashMap and HashSet."