equals() & hashCode()

⭐ Interview Importance: MEDIUM
⏱️ Revision Time: 5 min

TL;DR

  • equals() determines if two objects are logically equal (e.g., have the same ID or name).
  • hashCode() returns an integer hash for the object, used to place the object in hash-based collections like HashMap and HashSet.
  • The Contract: If two objects are equals(), they MUST have the same hashCode().

Concept

By default, the Object class uses memory addresses for both methods.

If you want to compare two Student objects based on their student ID, you must override equals(). But if you do that, you must also override hashCode().

Why? Because HashMaps group objects into “buckets” using their hash code. If two students are “equal” but have different hash codes, the HashMap will put them in different buckets. When you try to retrieve the student later, the HashMap will look in the wrong bucket and return null, effectively losing your data.

Examples

import java.util.Objects;

class Student {
    int id;
    String name;

    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public boolean equals(Object o) {
        // 1. Same memory reference?
        if (this == o) return true;
        // 2. Is it null or a different class?
        if (o == null || getClass() != o.getClass()) return false;
        
        // 3. Cast and compare actual values
        Student student = (Student) o;
        return id == student.id && Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        // Generate a hash based on the exact same fields used in equals()
        return Objects.hash(id, name);
    }
}

Interview Questions

Q: What happens if you override equals() but NOT hashCode()?
A: Your application will compile and run, but hash-based collections (like HashMap, HashSet) will break. You could add a Student object to a HashSet, and then set.contains(new Student(sameId)) will return false because the set looks in the bucket associated with the default memory-address hashcode, not your logical hashcode.

Q: Can two unequal objects have the same hash code?
A: Yes. This is called a Hash Collision. The hash code is just an integer (32-bit), so there are a limited number of hashes but infinite possible objects. If two different objects have the same hash code, they go into the same bucket in a HashMap. The Map then uses the equals() method to iterate through the bucket and find the exact right object.