Lesson 25 / 38
equals() & hashCode()
Override equals() and hashCode() correctly and together so your objects behave in HashMaps, HashSets, and everywhere equality matters.
Default is identity
Object's default equals() is just == (reference identity), and default hashCode() is derived from that identity. If two objects should be "equal" by their content (e.g. two Point(1,2)), you must override both methods yourself.
The contract
The golden rule: if a.equals(b) is true, then a.hashCode() == b.hashCode() must also be true. Break this and objects silently vanish inside HashMap/HashSet lookups. Use the same fields in both methods.
public final class Point {
private final int x, y;
// ... constructor, getters ...
@Override public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Point p)) return false;
return x == p.x && y == p.y;
}
@Override public int hashCode() {
return Objects.hash(x, y);
}
}Quick check
Quick check: You override equals() but forget hashCode(). What breaks?
- Nothing, they're independent
- Compilation fails
- "Equal" objects can land in different HashMap buckets and lookups fail
- equals() itself throws at runtime
Answer
"Equal" objects can land in different HashMap buckets and lookups fail — Hash-based collections use hashCode() to pick a bucket first, then equals() within it. Mismatched hashCode() means equal objects can be looked for in the wrong bucket and never be found.