Methods Common to All Objects
Obey the General Contract When Overriding equals
Overriding equals looks simple: check whether two objects match. In production systems, mistakes inside equals break collections, caches, and risk logic silently.
Java defines a strict contract.
An equals implementation must be:
Violating one rule leads to undefined behavior in List, Set, and Map.
The Symmetry Trap
Engineers often try to add “friendly” interoperability.
Example:
public final class CaseInsensitiveString {
private final String s;
@Override
public boolean equals(Object o) {
if (o instanceof CaseInsensitiveString)
return s.equalsIgnoreCase(((CaseInsensitiveString) o).s);
if (o instanceof String)
return s.equalsIgnoreCase((String) o);
return false;
}
}
Usage:
cis.equals("Hindi") // true
"Hindi".equals(cis) // false
Symmetry breaks.
Collections rely on symmetry. list.contains(cis) may return false even when the object exists.
Example
A trade ID wrapper compared directly with String breaks lookup inside reconciliation sets. Trades appear missing during end-of-day checks while sitting in memory.
The Transitivity Trap: ColorPoint
Base class:
class Point {
final int x, y;
}
Extended class:
class ColorPoint extends Point {
final Color color;
}
Questions appear:
Any choice violates either symmetry or transitivity once objects mix.
Java best practice's conclusion:
There is no safe way to extend an instantiable class and add a value field while preserving the equals contract.
The Fix: Composition Over Inheritance
Replace:
class ColorPoint extends Point
With:
class ColorPoint {
private final Point point;
private final Color color;
}
Now equality becomes,
No paradox. No mixed-type logic.
Example
Position objects extended through inheritance break equality inside portfolio aggregation. Composition keeps equality stable across pricing, margin, and reporting pipelines.
Always Override hashCode When Overriding equals
Rule:
If a.equals(b) returns true, then a.hashCode() must match b.hashCode().
Failure effect:
The object exists, yet stays unreachable.
Example
Risk caches keyed by instrument objects fail during lookup. Margin logic reports missing exposure while data remains allocated in memory.
Practical Rules
Takeaway
equals defines identity. Collections trust it blindly.
A small shortcut inside equals produces large system failures in trading, settlement, pricing, and reporting paths.
Correctness in equality protects correctness everywhere else.