equals() and hashCode() in Java — Why You Must Override Both
Overriding equals() without hashCode() breaks HashMap and HashSet behavior. Learn the contract between them and why they must be consistent.
Published September 22, 2026
equals() defines when two objects are considered logically equal. hashCode() returns an integer used by hash-based collections (HashMap, HashSet) to bucket objects efficiently. Java's contract requires that if two objects are equal() they must return the same hashCode() — but not necessarily the reverse.
Common causes
- Hash-based collections use hashCode() first to find the right bucket, then equals() to confirm an exact match within that bucket — if two equal objects have different hash codes, a HashSet/HashMap will fail to recognize them as duplicates
How to fix it
- Always override hashCode() whenever you override equals() — most IDEs and Lombok's @EqualsAndHashCode can generate a consistent pair automatically
- Base both methods on the same set of fields — if equals() compares fields a and b, hashCode() must incorporate exactly those same fields
- Use Objects.equals() and Objects.hash() (from java.util.Objects) to implement both concisely and correctly
Example
@Override
public boolean equals(Object o) {
if (!(o instanceof Point p)) return false;
return x == p.x && y == p.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}FAQ
What breaks if I override equals() but not hashCode()?
Putting the object in a HashSet or as a HashMap key can silently fail to detect duplicates or find existing entries, because the default hashCode() (based on memory address) won't match between two objects your equals() considers equal.