All 15 Collections Framework questions
More in Collections Framework
Advertisement
Back to results for “Collections”
Java › Collections Framework

What is the contract between equals() and hashCode() that a custom class must satisfy to work correctly as a HashMap key or HashSet element?

Intermediate

Answer

Any two objects considered equal via equals() MUST return the identical hashCode() value (though the converse isn't required -- unequal objects may share a hash code, called a collision, which is handled but should be rare for good performance); violating this contract (overriding equals() without also overriding hashCode() consistently) causes silently broken behavior in hash-based collections, since a HashMap uses hashCode() to locate the correct bucket first, then equals() to confirm the exact match within that bucket -- if two "equal" objects hash differently, a HashMap may fail to locate an entry that logically should be found, appearing to have simply lost data.
public class Point {
    private final int x, y;
    // constructor omitted

    @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);  // MUST be consistent with equals()
    }
}
Real-world example A bug report describing a HashSet<Point> that appears to allow "duplicate" points is traced to a Point class overriding equals() (correctly comparing x/y coordinates) but forgetting to also override hashCode(), causing two logically equal Point instances to land in different buckets and never be recognized as duplicates by the HashSet.

Common follow-ups: What happens if hashCode() is overridden but equals() is not, in terms of contract violation risk?;Why does Object's default hashCode() implementation (based on memory address) become invalid once equals() is overridden?