All topics
library
beginner

equals() & hashCode() Contract

Understand the contract between equals and hashCode, and what breaks when you violate it.

The equals/hashCode contract is the most important invariant in Java collections:

hashCode = a filing cabinet drawer number (tells you which drawer to look in). equals = comparing the actual document to confirm it's the right one. Wrong drawer number = you'll never find the document.

Key Concepts

1
1. If a.equals(b) is true, then a.hashCode() == b.hashCode() must be true. 2. If hashCode() differs, equals() must return false. 3. Objects that are not equal MAY have the same hash code (collisions are allowed).
2
If you override equals() without overriding hashCode(), HashMap/HashSet break. The map puts the key in a bucket based on hashCode(). When you look up with an equal key that has a different hashCode, it searches the wrong bucket and returns null.
3
equals() rules (contract): - Reflexive: x.equals(x) is true - Symmetric: x.equals(y) ↔ y.equals(x) - Transitive: if x.equals(y) and y.equals(z), then x.equals(z) - Consistent: multiple calls return the same result if objects don't change - x.equals(null) is always false
4
hashCode() rules: - Consistent: must return the same value during a single execution (unless equals-relevant fields change) - Equal objects must have equal hash codes - Use Objects.hash() for convenience, or hand-roll with prime multiplication for performance
5
A good hashCode distributes values evenly across buckets. A bad hashCode (e.g., always returning 1) turns a HashMap into a linked list — O(n) instead of O(1).