A class overrides equals but NOT hashCode. What is the likely result?
class P {
String n;
P(String n) { this.n = n; }
@Override public boolean equals(Object o) {
return o instanceof P p && p.n.equals(n);
}
}
Set<P> s = new HashSet<>();
s.add(new P("a"));
s.add(new P("a"));
System.out.println(s.size());Options
- Always 1, because equal objects always share one slot
- Likely 2: default hashCodes differ, so different buckets (Correct option)
- Always 0, since the set rejects objects with no hashCode
- A compile error, because
hashCodeis mandatory in Java
Answer
Most likely 2: the default hashCode differs per object, so they land in different buckets and equals is never even called
Why
Without an override, hashCode() comes from Object and is based on the object's identity, so two different P objects almost always get different hash codes.
HashSet uses the hash to pick a bucket. The two objects go to different buckets, so equals is never compared, and both are stored: size 2, even though equals says they are the same.
This breaks the contract. Fix: also override hashCode with Objects.hash(n).
Remember
Broken equals/hashCode contract = duplicates in hash collections.