`hashCode()` returns an integer used alongside `equals()` in Java object comparison. The essential rule is simple: objects considered equal must produce the same hash value. Breaking that relationship can make equality-based data structures behave unpredictably and create difficult debugging problems. section 7.0 section 7.8
The risk rises when `equals()` has nonstandard logic. If a two-field object treats `(f1, f2)` and `(f2, f1)` as equal, `Objects.hash(f1, f2)` is wrong because its result depends on argument order. A symmetric calculation such as `f1 + f2` matches that equality rule. Alternatively, normalize field order when constructing or modifying an immutable object; ordinary generated `equals()` and `hashCode()` then work. section 7.8
class TwoFields {
int f1, f2;
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
TwoFields twoFields = (TwoFields) o;
return f1 == twoFields.f1 && f2 == twoFields.f2 ||
f1 == twoFields.f2 && f2 == twoFields.f1;
}
}
This equality relation ignores field order, so its matching hash calculation must also ignore field order. The associated `f1 + f2` implementation supplies a symmetric hash. section 7.8
Case-insensitive equality can defeat case normalization
Using `equalsIgnoreCase()` for equality does not make `toLowerCase(Locale.ROOT).hashCode()` automatically safe. Some strings compare equal ignoring case while lowercasing produces different results, violating the contract. The illustrated Greek sigma values can compare equal yet cause a `Set` lookup to vary with the set’s contents. If preserving original case prevents construction-time normalization, make the equality and hashing transformations agree exactly. section 7.8
Avoid hand-written mismatch errors with practical safeguards:
- Generate `equals()` and `hashCode()` together in an IDE, especially after adding fields. section 7.15 section 7.6
- Use records for data holders when possible; Java 16 records receive compiler-generated `equals()` and `hashCode()` implementations. section 7.6
- Test custom equality with EqualsVerifier rather than relying only on manual cases. section 7.6
- Treat static-analysis warnings about comparison code as prompts for close inspection, not as warnings to suppress automatically. section 7.6
`hashCode()` is only one part of a broader comparison contract that includes `equals()`, `Comparable.compareTo()`, and `Comparator.compare()`. These methods are used implicitly by algorithms such as sorting and by structures such as `HashMap`, so comparison code should follow its documented contract rather than depend on accidental behavior. section 7.0 section 7.15

