The equals / hashCode Contract
The rules hash collections rely on, and exactly what breaks when you override only one of the two.
Open this lesson in the learning hubKey points
- The rule: objects that are
equalsmust return the samehashCode. Break it and hash collections lose data. HashMapuses the hash to pick a bucket, thenequalsto search inside it. Wrong bucket, never found.- Override both or neither. Doing just one is the classic cause of "my object vanished from the set".
- equals must be reflexive, symmetric, transitive, consistent, and false for
null.instanceofhandles null for free. - Use
Objects.hash(...)over the same fields as equals, and only fields that never change while in a set. - The cheapest correct answer is a
record. It generates both methods from its components.
Example
import java.util.HashSet;
import java.util.Objects;
import java.util.Set;
public class Main {
static class Loose { // inherits Object.equals: identity only
final String email;
Loose(String email) { this.email = email; }
}
static final class User {
private final String email;
User(String email) { this.email = email; }
@Override public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof User other)) return false; // handles null too
return email.equals(other.email);
}
@Override public int hashCode() {
return Objects.hash(email); // same fields as equals
}
}
public static void main(String[] args) {
Set<Loose> loose = new HashSet<>();
loose.add(new Loose("a@x.com"));
loose.add(new Loose("a@x.com"));
System.out.println("no contract -> size " + loose.size());
Set<User> users = new HashSet<>();
users.add(new User("a@x.com"));
users.add(new User("a@x.com"));
System.out.println("with contract -> size " + users.size());
System.out.println("contains? -> " + users.contains(new User("a@x.com")));
}
}
Equal objects must share a hash code, or hash collections quietly swallow them.
This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the OOP course, and every lesson in it is listed on the OOP contents page.