Suppose I need TreeSet with elements sorted with some domain logic. By this logic it doesn’t matter order of some elements that doesn’t equal so compare method can return 0, but in this case I couldn’t put them in TreeSet.
So, question: what disadvantages I’ll have from code like this:
class Foo implements Comparable<Foo>{}
new TreeSet<Foo>(new Comparator<Foo>(){
@Override
public int compare(Foo o1, Foo o2) {
int res = o1.compareTo(o2);
if(res == 0 || !o1.equals(o2)){
return o1.hashCode() - o2.hashCode();
}
return res;
}
});
Update:
Ok. If it should always be a consistency between the methods equals(), hashcode() and compareTo(), as @S.P.Floyd – seanizer and others said.
If it would be better or even good if I’ll remove Comparable interface and move this logic in Comparator (I can do it without broken encapsulation)? So it will be:
class Foo{}
new TreeSet<Foo>(new Comparator<Foo>(){
@Override
public int compare(Foo o1, Foo o2) {
//some logic start
if(strictliBigger(o1, o2)){ return 1;}
if(strictliBigger(o2, o1)){ return -1;}
//some logic end
if(res == 0 || !o1.equals(o2)){
return o1.hashCode() - o2.hashCode();
}
return res;
}
});
Update 2:
Would System.identityHashCode(x) be better than hashCode() if I don’t need stable sort?
While this might work, it is far from being a best practice.
From the SortedSet docs:
For objects that implement
Comparable, there should always be a consistency between the methodsequals(),hashcode()andcompareTo().I’m afraid a
SortedSetis just not what you want, nor will a GuavaMultiSetbe adequate (because it will not let you independently retrieve multiple equal items). I think what you need is aSortedList. There is no such beast that I know of (maybe in commons-collections, but those are a bit on the legacy side), so I implemented one for you using Guava’s ForwardingList as a base class. In short: this List delegates almost everything to anArrayListit uses internally, but it usesCollections.binarySearch()in it’sadd()method to find the right insertion position and it throws anUnsupportedOperationExceptionon all optional methods of theListandListIteratorinterfaces that add or set values at a given position.The Constructors are identical to those of
ArrayList, but for each of them there is also a second version with a customComparator. If you don’t use a custom Comparator, your list elements need to implementComparableorRuntimeExceptions will occur during sorting.