How should I override equals and hashcode method to avoid adding equal objects o HashSet?

I have studied similar examples and override these methods like this, but still get added to the HashSet<NamedObject> objects with the equal names BUT different id.

public class NamedObject {
    String name;
    BigInteger id;

    @Override
    public boolean equals(Object o) {
        if (this == o) {
            return true;
        }
        if (o == null || getClass() != o.getClass()) {
            return false;
        }

        NamedObject that = (NamedObject) o;
        return this.name.equals(that.getName());
    }

    @Override
    public int hashCode() {
        return id.hashCode();
    }
}
Jon Skeet
people
quotationmark

I have studied similar examples and override these methods like this, but still get added to the HashSet<NamedObject> objects with the equal names BUT different id.

Yes, because you're only using the id in the hash code, and only using the name in the equality check. HashSet<> will only call equals() when it finds an existing object with the same hash code as the one you're trying to add... if your IDs are different, it's highly unlikely that the hash codes will be different, so it's never calling equals with the object that has the same name.

Your hashCode() and equals() methods must be consistent with each other. You need to decide whether equality is based on name, ID, or both - and then use that in both hashCode() and equals().

From the Object.hashCode() documentation:

The general contract of hashCode is:

  • Whenever it is invoked on the same object more than once during an execution of a Java application, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified. This integer need not remain consistent from one execution of an application to another execution of the same application.
  • If two objects are equal according to the equals(Object) method, then calling the hashCode method on each of the two objects must produce the same integer result.
  • It is not required that if two objects are unequal according to the equals(java.lang.Object) method, then calling the hashCode method on each of the two objects must produce distinct integer results. However, the programmer should be aware that producing distinct integer results for unequal objects may improve the performance of hash tables.

Your methods break the middle of these requirements at the moment.

people

See more on this question at Stackoverflow