Reputation: 382
I was looking at some code and found one program where they have extended HashSet class of collection. They have created custom employee objects and inserted into Set without implementing Comparable or Comparator. They implemented logic to identify duplicate employee object so if object is already there They can perform update operation if object is not present they can do insert operation. I was trying to understand how set will identify duplicate object without implementiong Comparable or Comparator interface.
I have tried same and also tried to override Hashcode and equals method to understand how Set comparing objects. One thing I have found that while I am adding same object to set its generating same Hashcode. But its not calling equals method I have overrided.
class Employee {
int id;
String name;
Employee(int id, String name) {
this.id = id;
this.name = name;
}
@Override
public int hashCode() {
System.out.println("HashCode : " + super.hashCode());
return super.hashCode();
}
@Override
public boolean equals(Object o) {
System.out.println("Equals : " + super.equals(o));
return super.equals(o);
}
}
class LimitedHashSet extends HashSet<Employee> {
public boolean add(Employee e) {
if(!super.add(e)){
return false;
}
return true;
}
}
public class ExtendingHashSet {
public static void main (String[] args) {
Employee e0 = new Employee(1,"A");
Employee e1 = new Employee(2,"B");
LimitedHashSet obj = new LimitedHashSet();
System.out.println("Element added ? " + obj.add(e0) + "\n");
System.out.println("Element added ? " + obj.add(e1) + "\n");
System.out.println("Element added ? " + obj.add(e0) + "\n");
}
}
Hashcode is use to calculate bucket and equals method identifies its equals or not. So how its working here. Please check output below.
Output:
HashCode : 914424520 Element added ? true
HashCode : 110718392 Element added ? true
HashCode : 914424520 Element added ? false
Upvotes: 4
Views: 324
Reputation: 198341
Fundamentally, there is no magic.
HashSet
and all JDK hash-based collections blindly use the implementations of hashCode
and equals
definitions for your objects to determine if objects are the same or not. They just call the hashCode
and equals
methods, and however those work, that's what the hash collections use.
Part of the point of the use of the hashCode
method -- part of the point of hash-based data structures in the first place -- is to make it unlikely that the hash-based collection even has to bother calling the equals
method to check if two objects are the same. If the hashes aren't the same, then the objects are definitely not equal. So it would call the equals
method you have overridden if it needed to, but in your code, it doesn't need to bother calling equals
. Furthermore, it also checks reference equality before calling the equals
methods, because if two objects are ==
then they are definitely .equals
to each other.
Currently, you are adding e0
twice. By reference equality, e0 == e0
, so it doesn't bother calling .equals
-- it just finds the matching entry, checks that they're reference-equal, and keeps the existing entry without adding a new element. This is the correct behavior, by the way, since e0
is a duplicate of itself.
Upvotes: 4