← Back to Java

hashCode() and equals()

JavaMiddata-structuresjava

The Question

What is the importance of hashCode() and equals() methods in Java?

What a Strong Answer Covers

  • equals defines logical equality
  • hashCode for hash-based collections
  • equal objects must have same hashCode
  • override both together
  • contract

Senior-Level Answer

The `equals()` method defines logical equality between objects — whether two instances should be considered the same value. The `hashCode()` method returns an integer used by hash-based data structures to bucket objects efficiently. They are defined on `Object` and meant to be overridden together.

The contract between them, specified in the Java documentation, is: if two objects are equal according to `equals()`, they must return the same `hashCode()`. The reverse is not required — two objects with the same hash code need not be equal (hash collisions are allowed).

This contract is critical for `HashMap`, `HashSet`, and `Hashtable`. When you call `map.put(key, value)`, the map computes `key.hashCode()` to find the right bucket, then uses `equals()` to find the exact entry within that bucket. If you override `equals()` without overriding `hashCode()`, two logically equal objects may land in different buckets, making retrieval silently fail — the map will not find a key even though an equal one exists.

The reverse violation is less catastrophic but still a performance problem: if all objects return the same hash code (constant hash), every entry lands in the same bucket, turning O(1) lookups into O(n) linked list scans.

For correct implementations: `equals()` must be reflexive, symmetric, transitive, consistent, and return false for null. `hashCode()` should use the same fields that `equals()` uses. IDEs and `Objects.hash()` / `Objects.equals()` can generate compliant implementations. Java 16+ records auto-generate both based on their components.

A subtle production bug: using a mutable field in `hashCode()` is dangerous when that object is stored in a `HashSet`. Mutating the field after insertion changes the hash, putting the object in the wrong bucket — the set can no longer find or remove it.

What Separates a 2/3 from a 3/3

2/3 — Passing but Incomplete

Explains the contract (equal objects must have equal hash codes) and why violating it breaks HashMap/HashSet lookups.

3/3 — Strong Answer

Also covers the symmetric/transitive/reflexive equals contract, the performance implication of poor hash distribution, and the danger of mutable fields in hash keys.

Common Mistakes

  • Overriding equals() without overriding hashCode(), causing silent HashMap lookup failures.
  • Assuming equal hash codes imply equal objects — conflating the one-directional contract.
  • Using mutable fields in hashCode() for objects stored in hash-based collections.

Follow-Up Questions

  • What happens if you put an object into a HashSet, then mutate a field used in its hashCode? — The object moves to a new bucket conceptually but the set still holds the old bucket index — it becomes lost and unremovable.
  • How does HashMap use both hashCode() and equals() during a get() call? — hashCode() identifies the bucket; equals() scans the bucket's chain/tree to find the exact entry.
  • What is the risk of implementing hashCode() to always return a constant value? — All keys collide into one bucket, degrading HashMap to a linked list with O(n) lookup.

Related Questions

  • JVM vs JRE vs JDK
  • Java Platform Independence
  • How JVM Works
  • Main Features of Java
  • public static void main

Can You Explain This Cold?

Reading the answer is step one. Explaining it unprompted — under interview pressure — is what actually matters. Get AI-graded feedback on your answer with follow-up probes on your weak points.

Get Graded — Free Assessment
GrindQuestionsAITechnical interview assessment
TermsPrivacyAbout