Posted in

Contract between equals() and hashCode() methods on HashMap?

🔹 Why this happens

By default, if you don’t override equals() and hashCode(),
Java uses the ones from the Object class.

public boolean equals(Object obj) {
    return (this == obj);  // compares memory address
}

public int hashCode() {
    // memory-based hash code
}

So even if two objects have the same data, they are different in memory, and the HashMap will treat them as different keys.


🔹 Example

class Employee {
    int id;
    String name;
}

public class Test {
    public static void main(String[] args) {
        HashMap<Employee, String> map = new HashMap<>();

        Employee e1 = new Employee();
        e1.id = 101; e1.name = "Rupendra";

        Employee e2 = new Employee();
        e2.id = 101; e2.name = "Rupendra";

        map.put(e1, "Engineer");
        map.put(e2, "Consultant");

        System.out.println(map.size());  // ❌ Output: 2 (duplicate stored)
    }
}

Even though both Employee objects have identical data (id=101, name="Rupendra"),
the map stores them as two separate entries — because:

  • e1.equals(e2)false (different memory references)
  • e1.hashCode() != e2.hashCode() (randomly different)

🔹 What happens internally

  1. HashMap calls hashCode() to find a bucket.
  2. It checks if a key already exists in that bucket using equals().
  3. Since your class doesn’t override them, equals() always returns false.
    → So the map thinks it’s a new key and inserts a new entry.

🔹 Correct Implementation (to avoid duplicates)

To make the map recognize equal objects as the same key:

class Employee {
    int id;
    String name;

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Employee)) return false;
        Employee e = (Employee) o;
        return id == e.id && name.equals(e.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
}

Now:

Employee e1 = new Employee(101, "Rupendra");
Employee e2 = new Employee(101, "Rupendra");

map.put(e1, "Engineer");
map.put(e2, "Consultant");

System.out.println(map.size()); // ✅ Output: 1

🔹 Summary Table

Caseequals() and hashCode() Correct?Result in HashMap
Not overridden❌ NoDuplicates possible
Only equals() overridden❌ NoStill duplicates
Only hashCode() overridden❌ NoStill duplicates
Both overridden properly✅ YesNo duplicates

Leave a Reply

Your email address will not be published. Required fields are marked *