Why Overriding hashCode() Matters: Java HashSet Gotchas Explained
This article explains the purpose of Java's hashCode() and equals() methods, outlines the rules for overriding them, demonstrates common pitfalls with HashSet through a concrete code example, and clarifies why both methods must be overridden when using custom objects as HashMap keys.
Let's discuss Java's hashCode() and equals() methods, their roles in collections, and the rules for correctly overriding them.
hashCode()
hashCode is used for fast lookup in structures like Hashtable and HashMap, determining an object's storage address.
If two objects are considered equal according to equals(Object), they must have the same hashCode.
When overriding equals(), you should also override hashCode(), and both should use the same fields.
Identical hashCodes do not guarantee object equality; they only indicate that the objects reside in the same bucket of a hash‑based collection.
equals(Object obj)
If a class does not override equals(Object), the default implementation compares object references (==).
If overridden, equality is determined by the custom logic, returning true for equal objects and false otherwise.
Demo code illustrating common mistakes:
public class MyClass {
public static void main(String[] args) {
HashSet books = new HashSet();
books.add(new A());
books.add(new A());
books.add(new B());
books.add(new B());
books.add(new C());
books.add(new C());
System.out.println(books);
}
}
class A {
// equals always returns true, but hashCode is not overridden
@Override
public boolean equals(Object o) {
return true;
}
}
class B {
// hashCode always returns 1, but equals is not overridden
@Override
public int hashCode() {
return 1;
}
}
class C {
public int hashCode() {
return 2;
}
@Override
public boolean equals(Object o) {
return true;
}
}Results observed from the demo:
Even though two A objects are equal via equals(), HashSet treats them as distinct because hashCode() was not overridden.
Two B objects share the same hashCode, yet HashSet still stores them as separate entries.
If equals() returns true but hashCode() differs, the objects end up in different buckets, violating the Set contract.
When hashCodes collide but equals() returns false, HashSet must handle multiple entries in the same bucket, which can degrade performance.
When using an object as a HashMap key, you must override both equals() and hashCode() in the custom class.
Otherwise, the default implementations inherited from Object are used, which compare only reference identity.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
