equals and hashCode contract
The Contract: if a.equals(b), then a.hashCode() and b.hashCode() must be equal. equals must be reflexive, symmetric, and transitive.
HashSet and HashMap use hashCode for bucket selection and equals for precision. Violations lead to "lost" elements.
Practice: all fields used by equals should also be included in hashCode. Avoid mutable fields as keys.
Contract in the JDK API: Object.equals [1].
Where used
Without a correct contract, HashMap/HashSet, ORM entities in sets, and deduplication in pipelines break. Each domain class that serves as a map key (UserId, Coordinate, Money) needs both methods to be consistent.
Depth
Business equality is modeled by equals. It must be reflexive, symmetric, transitive, and consistent over unchanged states. The hash code condenses the same relevant properties for quick selection.
If two objects are business equal, they must land in the same hash area. The reverse does not hold because different objects may collide. Therefore, a equality check still follows the hash check.
Inheritance complicates symmetric equality when a subclass has additional relevant fields. Immutable value objects or composition often provide a clearer contract than an extendable equality hierarchy.
Difficulty levels
- Check the properties of an equivalence relation.
- Distinguish acceptable collisions from contract violations.
- Assess equality in an inheritance hierarchy.
Pitfalls
Overriding only one of the two methods damages hash-based collections. Mutable equality fields also make already inserted keys unreliable.
Sources
Tasks
Card Info
- Topic: Algorithms and Data Structures
- Difficulty: Intermediate
- Completed: 0 users