javahashsethashcode

Duplicate custom objects are getting added to Hashset


I have an Employee class having 2 attributes id and name. I am overriding the hashcode and equals method as given below.

Employee.java:

import java.util.Objects;

public class Employee {

    private int id;
    private String name;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee) obj;
        if (id != other.id)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + "]";
    }
}

And now i have a test class where i am creating an object of employee class with name "Chris Gayle" and adding it to HashSet. After that i am modifying the name of this existing employee object to "Kieron Pollard" and i am adding this modified employee object again to hashset.

TestSet.java

import java.util.HashSet;
import java.util.Set;

public class TestSet {

 public static void main(String[] args) {
     Set<Employee> hashSet = new HashSet<Employee>();

     Employee emp1 = new Employee();
     emp1.setId(1);
     emp1.setName("Chris Gayle");

     hashSet.add(emp1);

     System.out.println(hashSet);

     emp1.setName("Kieron Pollard");
     hashSet.add(emp1);
     System.out.println(hashSet.size());
     System.out.println(hashSet);
}

}

When i print the content of hashset i gives the same employee object two times as given below.

[Employee [id=1, name=Chris Gayle]]
2
[Employee [id=1, name=Kieron Pollard], Employee [id=1, name=Kieron Pollard]]

Since, set doesn't allow duplicate elements but in the output we are getting duplicates in above scenario. So, what is the correct way to handle this kind of behaviour.


Solution

  • You shot yourself in the foot here.

    @Override
    public int hashCode() {
        return Objects.hash(id, name);
    }
    

    If hashCode is defined by the id & name & you change the name before adding the object to a HashSet again, you'll obviously get a duplicate entry. Reminder: the uniqueness of an object is determined by the hashCode - and that's what HashSet uses to determine if the object is already in the Set.

    What's your uniqueness criterion? If id is meant to be unique, use only id in the hashCode.

    @Override
    public int hashCode() {
        return Objects.hash(id);
    }