Skip to content
UniCircle
TipEngineeringB.Tech / B.E., BCA, MCA

Java equals and hashCode: the contract and why HashSet breaks without it

What equals and hashCode must promise each other, a short demo of a HashSet holding 'duplicates' when hashCode is missing, and how records do it for you.

By UniCircle team2 min readPublished 22 Oct 2026Undergraduate

The rule: if two objects are equal according to equals, they must return the same hashCode. HashSet and HashMap first use hashCode to find a bucket and only then call equals. Override one without the other and lookups quietly fail.

Java
import java.util.*;
public class StudentKey {
  static class Student {
    final String roll; final String name;
    Student(String roll, String name) { this.roll = roll; this.name = name; }
    @Override public boolean equals(Object o) {
      if (this == o) return true;
      if (!(o instanceof Student)) return false;
      return roll.equals(((Student) o).roll);
    }
    @Override public int hashCode() { return Objects.hash(roll); }
  }
  static class NoHash {
    final String roll;
    NoHash(String roll) { this.roll = roll; }
    @Override public boolean equals(Object o) { return o instanceof NoHash n && n.roll.equals(roll); }
  }
  record Course(String code, int credits) {}
  public static void main(String[] args) {
    Set<Student> good = new HashSet<>(List.of(new Student("22CS101", "Asha")));
    good.add(new Student("22CS101", "Asha K"));
    Set<NoHash> bad = new HashSet<>(List.of(new NoHash("22CS101")));
    bad.add(new NoHash("22CS101"));
    Set<Course> courses = new HashSet<>(List.of(new Course("CS301", 4)));
    courses.add(new Course("CS301", 4));
    System.out.println(good.size() + " " + bad.size() + " " + courses.size());
  }
}
text
1 2 1
  • Student overrides both, so the second student with the same roll number is treated as a duplicate.
  • NoHash overrides only equals. The two objects get different default hash codes, land in different buckets, and the set holds two "equal" objects.
  • A record generates equals, hashCode and toString from its fields automatically, which is why records make good map keys.

Getting it right

  • Use the same fields in both methods, and only fields that do not change while the object sits in a set or map.
  • Objects.hash(a, b, c) is an easy correct hashCode.
  • Use getClass() instead of instanceof in equals if subclasses must never equal the parent class.

#java#equals#hashcode#oop

Sources and further reading

Practise this as an interview question

Written by the UniCircle team, checked by an editor on 22 Oct 2026. It is not official policy of any university. Exam patterns and rules change; confirm dates and rules on the official website.

Keep reading