First look at the following code
Class worker implements comparable <worker> {private int age; private string name; public worker (INT age, string name) {This. setage (AGE); this. setname (name) ;}@ overridepublic int hashcode () {final int prime = 31; int result = 1; Result = prime * result + age; result = prime * result + (name = NULL )? 0: Name. hashcode (); return result ;}@ overridepublic Boolean equals (Object OBJ) {If (this = OBJ) return true; If (OBJ = NULL) return false; if (getclass ()! = Obj. getclass () return false; worker Other = (worker) OBJ; If (name = NULL) {If (other. Name! = NULL) return false;} else if (! Name. equals (Other. name) return false; return true ;}@ overridepublic int compareto (worker) {return New INTEGER (getage ()). compareto (New INTEGER (worker. getage ()));}... // setter/getter method}
Public static void main (string [] ARGs) {<span style = "white-space: pre "> </span> treeset <worker> set = new treeset <worker> (); set. add (new worker (21, "tester 1"); set. add (new worker (22, "tester 2"); set. add (new worker (21, "tester 3"); system. out. println (set. size ());}
What is the output result?
The original intention of the code writer should be to set three workers in order by age.
However, the result of the execution is 2, and then we can see that the tester 1 has no more than 2 and 3.
Why? Check the source code and find that the add method of treeset is defined as follows:
public boolean add(E paramE) { return this.m.put(paramE, PRESENT) == null; }
Here, this. m is treemap, and its put method is defined as follows:
public V put(K paramK, V paramV) { Entry localEntry1 = this.root; if (localEntry1 == null) { compare(paramK, paramK); this.root = new Entry(paramK, paramV, null); this.size = 1; this.modCount += 1; return null; } Comparator localComparator = this.comparator; Entry localEntry2; int i; if (localComparator != null) { do { <span style="color:#ff0000;">localEntry2 = localEntry1; i = localComparator.compare(paramK, localEntry1.key); if (i < 0) { localEntry1 = localEntry1.left; } else if (i > 0) { localEntry1 = localEntry1.right; } else { return localEntry1.setValue(paramV); }</span> } while (localEntry1 != null); } else { if (paramK == null) { throw new NullPointerException(); } localObject = (Comparable)paramK; do { <span style="color:#ff0000;">localEntry2 = localEntry1; i = ((Comparable)localObject).compareTo(localEntry1.key); if (i < 0) { localEntry1 = localEntry1.left; } else if (i > 0) { localEntry1 = localEntry1.right; } else { return localEntry1.setValue(paramV); }</span> } while (localEntry1 != null); } Object localObject = new Entry(paramK, paramV, localEntry2); if (i < 0) { localEntry2.left = ((Entry)localObject); } else { localEntry2.right = ((Entry)localObject); } fixAfterInsertion((Entry)localObject); this.size += 1; this.modCount += 1; return null; }
As shown in the red code above, the root of the add method in the treeset does not use the equals method to determine whether the two elements are equal. Instead, the compareto method is used to determine the position of the added element in the set.
To implement the desired results, the compareto method in worker should be modified
@Overridepublic int compareTo(Worker worker) {int index = getName().compareTo(worker.getName());if(index != 0){index = new Integer(getAge()).compareTo(new Integer(worker.getAge()));}return index;}
So we can get the expected results.
Conclusion: In treeset, determining that the two elements in the set are equal does not use the equals method, but uses the compareto method.
How the add method works for interesting treeset Problems