I posted some code here which correctly solved a problem the poster had. OP wanted to remove duplicates and bring certain special items to the top of a list. I used a TreeSet
with a special Comparable
class which wrapped the Locale
they were working with to achieve what they wanted.
I then got to thinking ... as you do ... that I was eliminating duplicates by returning 0
from the compareTo
method, not by returning true
from an equals
implementation as one would need to do to correctly indicate a duplicate in a Set
(from the definition of a Set
).
I have no objection to using this technique but am I using what might be considered an undocumented feature? Am I safe to assume that doing this kind of thing going forward will continue to work?
It seems like this is pretty well documented in JavaDoc of
TreeSet
(bold mine):Here is an example of the only (?) JDK class that implements
Comparable
but is not consistent withequals()
:decimals
at the end have three values because42
,42.0
and42.00
are not equal as far asequals()
is concerned. But if you replaceHashSet
withTreeSet
, the resulting set contains only 1 item (42
- that happened to be the first one added) as all of them are considered equal when compared usingBigDecimal.compareTo()
.This shows that
TreeSet
is in a way "broken" when using types not consistent withequals()
. It still works properly and all operations are well-defined - it just doesn't obey the contract ofSet
class - if two classes are notequal()
, they are not considered duplicates.See also