Reader Guohong Liu wrote to me to point out a bug in my book Java Examples in a Nutshell.. The bug is with example 4-6 whch is an example of using threads to implement the java.util.Timer class. The particular details aren't interesting, but the overall cautionary tale is.
In this example, I use a java.util.TreeSet to maintain a list of TimerTask objects sorted in execution order. What I forgot is that the SortedSet interface uses the comparator to determine object equality as well as ordering. When there were two TimerTask objects with the same scheduled execution time, my compartor returned 0 to indicate that I didn't care about the order of these two objects.
In fact, what happened in this case is that the TreeSet treated the two task objects as equal in the sense of the equals() method. And, since it is a set, after all, it only allowed one of the objects to be inserted. One task would get lost and never be executed.
So, if you want to use a SortedSet to implement a sorted list, as I did, it is not sufficient to simply rely on the identity-based Object.equals() method. You have to code your compareTo() method or your Comparator object carefully so that they only return 0 if the objects being compared are in fact the same object.
This is all clearly spelled out in the SortedSet javadoc. The sorting order must be "consistent with equals()". My class inherited the identity-based equals() method from Object. But my comparator could return 0 even when equals() would return false for the same two objects.



