Java · OOP, JVM and backend craft
What is the contract between equals and hashCode?
Short answer
equals defines logical equality and hashCode must be consistent with it. Equal objects must return the same hash code, otherwise hash-based collections cannot find them reliably.
The contract has three practical rules. equals must be reflexive, symmetric and transitive. It must be consistent while the object is used as a key. And if two objects are equal, they must produce the same hashCode. Unequal objects may share a hash code, which is a collision, but equal objects may not.
public final class Point {
private final int x;
private final int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public boolean equals(Object other) {
if (this == other) {
return true;
}
if (!(other instanceof Point)) {
return false;
}
Point point = (Point) other;
return x == point.x && y == point.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
}How hash collections use the contract
- HashMap computes the hash to choose a bucket, then calls equals to find the exact key
- If equals is overridden without hashCode, equal keys can land in different buckets and become unreachable
- If a mutable field used in hashCode changes after insertion, the entry is effectively lost
- Records generate a consistent equals and hashCode from their components
Use getClass comparison when subclass equality must be strict, and instanceof when a subtype should be able to equal its parent representation, which is uncommon and risky. Prefer composition over inheritance for value types to avoid these questions.
Follow-ups you should expect
Interviewers use these to check whether the first answer was understanding or memorisation.
- 1What happens if you override equals but not hashCode?
- 2Can two unequal objects share a hash code?
- 3Why are mutable fields dangerous in hash keys?
- 4How do records implement equals and hashCode?
Say it in the interview
equals defines logical equality, and hashCode must agree with it: equal objects need the same hash, while unequal objects may collide. HashMap uses the hash to select a bucket and equals to confirm the key. If I override equals without hashCode, equal keys can become unreachable. I also keep key fields immutable, because changing them after insertion breaks lookups, and I prefer records for simple value types.
Use this as a model, not a script. Saying it in your own words is what makes it survive follow-up pressure.
Related questions
Reading is step one
Now say it out loud.
Understanding an answer and delivering it under pressure are different skills. Rehearse this topic in a live Java mock interview and get scored feedback on depth, clarity and confidence.