When we store or search for any element, HashSet/HashMap uses hashCode() and equals() method as produce joint result
We know that storing
String, Wrapper like class works fine with HashSet,HashMaps because they String,Wrapper already overridden hashCode() and equals()..... more better way your hashCode() is implemented, faster with be search in HashSet/HashMap.
Now in Anthony;s example, Day class overrides hashCode() which is legal but not efficient, because it provides one bucket for all....but good thing is that equals is better as it compares day....
I am going to discuss the adding procedure by HashSet in your example in detail.
1. JVM executes hashset.add(d1);
This statement first calls hashCode() that returns 9.
As no other element there and d1 is the very first element in HashSet, hence equals method is not called.
So d1 is stored in a bucket with number 9
hashset.size()-----------> 1
2.JVM executes hashset.add(d2)
This statement first calls hashCode() that return 9.
Now hashset find the bucket with 9 for storing d2, but one element does already exist there (d1).
So hashset will decide to compare d2 with d1 by calling d2.equals(d1) which returns false.
Hence both objects are not equals but will be stored in same bucket of number 9
hashset.size()-----------> 2
3.JVM executes hashset.add(d3)
This statement first calls hashCode() that return 9.
Now hashset find the bucket with 9 for storing d3, but two elements already exist there (d1,d2).
So hashset will decide to compare d3 with both d1 and d2.....till get a result true...hopefully...for
d3.equals(d1)...result is true.
Hence both objects(d3,d1) are equals and as per rule, HashSet does not allow duplicate objects...so d3 is not stored.
again hashset.size()-----------> 2
run the code below for getting complete flow.
import java.util.HashSet;
public class TestHashCode {
public static void main(String[] args)
{
Day d1 = new Day("Monday");
Day d2 = new Day("Tuesday");
Day d3 = new Day("Monday");
HashSet hashset = new HashSet();
System.out.println("adding d1....");
hashset.add(d1);
System.out.println("adding d2....");
hashset.add(d2);
System.out.println("adding d3....");
hashset.add(d3);
System.out.println("adding completed....");
System.out.println("size:" + hashset.size());
}
}
class Day {
private String day;
public Day(String day)
{
this.day = day;
}
public boolean equals(Object obj)
{
System.out.println("equals() method "+this.day+".equals("+((Day) obj).day+")");// do not try it at home
if (obj instanceof Day && ((Day) obj).day.equals(this.day)) {
System.out.println("Yes in equals() "+day);
return true;
}
return false;
}
public int hashCode() {
System.out.println("hashCode()");
return 9;
}
}
OUTPUT is
---------------------------------------------------
adding d1....
hashCode()
adding d2....
hashCode()
equals() method Tuesday.equals(Monday)
adding d3....
hashCode()
equals() method Monday.equals(Tuesday)
equals() method Monday.equals(Monday)
Yes in equals() Monday
adding completed....
size:2
------------------------------------------