Question
Why doesn't HashSet in Java recognize that two objects are equal?
HashSet<MyObject> set = new HashSet<>();
set.add(new MyObject("Example"));
set.add(new MyObject("Example")); // Might be treated as different objects if equals() is not overridden.
Answer
In Java, the HashSet is part of the Java Collections Framework and relies on the equals() and hashCode() methods of the objects it contains to determine equality. If these methods are not overridden correctly, HashSet may treat two logically equivalent objects as different, leading to unexpected behavior.
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (!(obj instanceof MyObject)) return false;
MyObject other = (MyObject) obj;
return this.name.equals(other.name);
}
@Override
public int hashCode() {
return this.name.hashCode();
}
Causes
- The equals() method is not overridden: If the class of the objects stored in the HashSet does not override the equals() method, the default implementation from Object will be used, which checks for reference equality rather than logical equality.
- The hashCode() method is not overridden: If you override equals() but do not override hashCode(), then two equal objects may produce different hash codes, leading to incorrect behavior in the HashSet.
- Inconsistent implementation between equals and hashCode: It is vital to make sure that if two objects are equal according to equals(), they must have the same hash code.
Solutions
- Override the equals() method to define logical equality between objects: Ensure that this method checks all relevant fields that represent the state of the object.
- Override the hashCode() method whenever you override equals(): Make sure that equal objects return the same hash code. Use the same fields in hashCode() that are used in equals().
- Use debugging: Print out the hash codes of the objects to ensure they are the same when they are supposed to be equal.
Common Mistakes
Mistake: Failing to override hashCode() when overriding equals()
Solution: Always override both methods together to maintain the contract of HashSet.
Mistake: Using mutable fields in equals() and hashCode()
Solution: Always use final fields, or fields that do not change after the object is constructed.
Helpers
- HashSet Java
- Java HashSet equal objects
- equals method Java
- hashCode method Java
- Java Collections Framework