When working on recent project, here is a common mistake I encountered with an equivalent code snitbit
If HashSet does not allow duplicates, why do the following two objets (w1 and w2 return true)?
public static void main(String[] args) {
Set<Widget> widgets = new HashSet<Widget>();
Widget w1 = new Widget("a");
Widget w2 = new Widget("a");
Iterator it = widgets.iterator();
while(it.hasNext()) {
System.out.println(it.next() );
System.out.println(w1.equals(w2) ); // true
}
</span>
public class Widget{
String name;
Widget(String s){
this.name = s;
}
public String toString(){
return this.name;
}
public boolean equals(Object o){
if((o instanceof Widget) && (this.name.equals(((Widget)o).name)))
return true;
else
return false;
}
}
Issue
According to the Java specification, whenever you override equals() you need to override hashCode() too.
HashSet uses both hashCode() first to find the right bucket, but then it still needs to use equals(), because the hashcode is allowed to be ambigous.
It does this because it needs the hash code (a number representing the object) to determine where in the set to store that Object.
However in the case of TreeSet, it depends on the return value of compareTo (or compare) methods. If the return value is 0, it won’t allow one to do an insertion.