Duplicates can be stored if don’t define equals() and hashCode() method correctly.
🔹 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
HashMapcallshashCode()to find a bucket.- It checks if a key already exists in that bucket using
equals(). - Since your class doesn’t override them,
equals()always returnsfalse.
→ 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
| Case | equals() and hashCode() Correct? | Result in HashMap |
|---|---|---|
| Not overridden | ❌ No | Duplicates possible |
Only equals() overridden | ❌ No | Still duplicates |
Only hashCode() overridden | ❌ No | Still duplicates |
| Both overridden properly | ✅ Yes | No duplicates |