Why 90% of Developers Fail with This HashMap Pitfall (Can You Solve It?)
The article explains why a HashMap lookup can return null even when key objects have identical fields, showing that the default equals and hashCode implementations compare memory addresses, and demonstrates how overriding both methods fixes the issue and avoids real‑world bugs.
Many Java developers encounter a puzzling situation: inserting an Employee object into a HashMap and later retrieving it with another Employee that has the same id and name returns null. The root cause is the default implementations of equals() and hashCode(), which operate on object identity rather than field values.
Example without overriding equals and hashCode
class Employee{int id; String name; Employee(int id,String name){this.id=id;this.name=name;}} Employee e1 = new Employee(101, "Naveen");
Employee e2 = new Employee(101, "Naveen");
Map<Employee, String> map = new HashMap<>();
map.put(e1, "Stored Value");
System.out.println(map.get(e2)); // nullEven though e1.id == e2.id and e1.name.equals(e2.name), the map treats them as different keys because the default hashCode() is based on the object's memory address and equals() compares references ( ==).
How HashMap Performs a Lookup
The lookup consists of three steps:
Compute hash: int hash = key.hashCode(); – for e1 and e2 the hashes differ because they are different objects.
Locate bucket: index = hash % capacity; – different hashes place the keys in different buckets.
Search within bucket: get(e2) looks only in e2 's bucket, where e1 is absent, so the result is null.
Correct Approach: Override both equals and hashCode
import java.util.Objects;
class Employee {
int id;
String name;
Employee(int id, String name) { this.id = id; this.name = 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 && Objects.equals(name, e.name);
}
@Override
public int hashCode() {
return Objects.hash(id, name);
}
}Testing the same scenario after the override yields the expected value:
Employee e1 = new Employee(101, "Naveen");
Employee e2 = new Employee(101, "Naveen");
Map<Employee, String> map = new HashMap<>();
map.put(e1, "Stored Value");
System.out.println(map.get(e2)); // Stored ValueWhat Changes Internally
hashCode consistency: hash(e1) == hash(e2) → both keys go to the same bucket.
equals returns true: the bucket comparison succeeds.
Value is returned: the lookup chain completes successfully.
Rule of Thumb
Whenever you override equals() , you must also override hashCode() .
If you only override equals(), the two objects will have different hashes, land in different buckets, and the map will still return null.
Real‑World Impact
Misusing HashMap keys can cause cache misses, duplicate entries, memory waste, and hard‑to‑reproduce bugs in production systems such as Redis key wrappers, local caches like Caffeine, and deduplication logic.
Simplified HashMap Structure
The essential two‑step process is: hashCode() decides which bucket the key goes to. equals() decides whether the key in that bucket matches the lookup key.
Both steps are indispensable for correct behavior.
Key Takeaways
HashMap determines key equality using both hashCode() and equals(), not just equals().
The default implementations rely on memory addresses, not business fields.
Overriding both methods ensures logical consistency and prevents subtle bugs.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
LuTiao Programming
LuTiao Programming is a friendly community offering free programming lessons. We inspire learners to explore new ideas and technologies and quickly acquire job-ready skills.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
