State the equals contract (all five properties). — Cracked Java
// Object-Oriented Programming · equals, hashCode, toString — the Object Contract
MidTheoryEPAMAmazon

State the equals contract (all five properties).

The equals contract has five properties: reflexive, symmetric, transitive, consistent, and non-null. Any class that overrides equals must honor all five; violating any one breaks hash collections, lists, and the JDK's own utilities in subtle ways.

The five properties

  1. Reflexivex.equals(x) is true for every non-null x.
  2. Symmetricx.equals(y) == y.equals(x) for every non-null x, y.
  3. Transitive — if x.equals(y) && y.equals(z) then x.equals(z).
  4. Consistent — repeated calls return the same result as long as the compared state doesn't change.
  5. Non-nullx.equals(null) returns false, never throws NullPointerException.

The canonical hand-written implementation

public final class Money {
    private final long cents;
    private final String currency;

    public Money(long cents, String currency) {
        this.cents = cents;
        this.currency = Objects.requireNonNull(currency);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;                           // reflexive fast-path
        if (!(o instanceof Money other)) return false;        // type + null check
        return cents == other.cents
            && currency.equals(other.currency);               // field-by-field
    }

    @Override
    public int hashCode() { return Objects.hash(cents, currency); }
}

The instanceof pattern (Java 16+) handles null for free: null instanceof Money is always false.

Why each property matters in practice

PropertyWhat breaks when violated
ReflexiveList.contains(x) may return false even when x is in the list.
Symmetricset.contains(a) and set.contains(b) give different answers depending on insertion order.
TransitiveA HashSet can hold three pairwise-equal objects, all "duplicates" of each other.
ConsistentUsing System.currentTimeMillis() or a mutable field makes keys "vanish" from HashMap.
Non-nullNPE inside Collection.remove(null) because the JDK routinely calls equals(null).

A subtle violation: comparing a BigDecimal

BigDecimal a = new BigDecimal("1.0");
BigDecimal b = new BigDecimal("1.00");
a.equals(b);            // false — different scale
a.compareTo(b) == 0;    // true — same numeric value

BigDecimal.equals checks scale and value, so equal-numerically values are not equals-equal. This is famously inconsistent with compareTo and breaks TreeSet<BigDecimal> (which uses compareTo) vs HashSet<BigDecimal> (which uses equals).

Mark your status