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.
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);
}