Equality & Hashing
The equals/hashCode contract, == vs equals(), and common equality and hashing pitfalls.
3 questions
JuniorTheoryVery commonWhat is the difference between == and equals() in Java?
What is the difference between == and equals() in Java?
For objects == compares references (identity) — whether both point to the same instance — while equals() compares logical content and is overridable. For primitives == compares values directly. So for String and wrapper types like Integer always use equals(), since == may only test object identity and two equal-valued objects can be distinct instances.
Common mistakes
- ✗Using
==to compareStringcontent and being misled when interned literals happen to match - ✗Assuming
equals()compares identity instead of overridable logical content - ✗Forgetting that
==on primitives compares values, not references
Follow-up questions
- →Why can
==on two equalStringliterals return true but fail withnew String()? - →What does the default
Object.equals()do if a class never overrides it?
MiddleTheoryCommonWhat is the equals()/hashCode() contract in Java?
What is the equals()/hashCode() contract in Java?
The contract: if two objects are equal by equals(), they MUST return the same hashCode(). The reverse need not hold — unequal objects MAY share a hash (a collision). So whenever you override equals() you must override hashCode() consistently, using the same fields. Break this and hash-based collections like HashMap or HashSet misbehave: an object lands in one bucket but is searched for in another, so lookups silently miss.
Common mistakes
- ✗Overriding
equals()but leaving the inheritedhashCode(), breakingHashMaplookups - ✗Assuming equal hash codes imply equal objects, treating collisions as impossible
- ✗Using different fields in
equals()andhashCode()so consistency is violated
Follow-up questions
- →Why does a key get lost in a
HashMapwhen onlyequals()is overridden? - →Is returning a constant from
hashCode()correct, and what does it cost?
SeniorTheoryOccasionalWhat are the common equality and hashing pitfalls in Java?
What are the common equality and hashing pitfalls in Java?
Key traps: overriding equals() but not hashCode(), so a key vanishes from a HashMap after insertion; including mutable fields in hashCode(), so an object moves bucket after being stored and can never be found; skipping the null and type checks inside equals(), causing wrong results or NullPointerException; and using == on autoboxed Integer, where the −128..127 cache makes it sometimes-true and otherwise false, masking bugs.
Common mistakes
- ✗Putting mutable fields in
hashCode(), so a stored key relocates and lookups fail - ✗Comparing boxed
Integerwith==and passing tests only inside the cached −128..127 range - ✗Omitting the null or type guard in
equals(), throwing or returning wrong results
Follow-up questions
- →Why does mutating a field used in
hashCode()make aHashSetelement unreachable? - →How does
Integer.valueOfcaching make==unreliable across the int range?