I have a custom class where I have implemented both Comparable
and Comparator
interface. The sorting/comparison logic is opposite for the two.
consider the below class as an example:
class Test implements Comparable<Test>, Comparator<Test>{
private Integer field;
public Test(Integer field){this.field = field;}
@Override
public int compareTo(Test obj){
return this.field.compareTo(obj.field);
}
@Override
public int compare(Test t1, Test t2){
return -t1.compareTo(t2);
}
//impl of equals, hashCode and toString omitted for this example
}
So when I add objects of Test
to a TreeSet
by default it is sorting by the implementation of the Comparable
which is understood as per the JDK source. So is there any flag/switch to switch to the sorting represented by the Comparable
implementation? I do not want to pass another Comparator
to the TreeSet
constructor.
There is a misconception on your side:
- A
Comparable
class has objects that can be compared against each other (for example by a container that wants to sort them - A
Comparator
is the thing that compares two objects of some class.
There is no need for you to make your class implement both.
And worse: remember that code communicates intent: the idea that your class implements both interfaces, but in "opposite" ways, that is very much counter intuitive. It will simply confuse your readers, and can lead to all kinds of bugs, just because your code does something that few experienced java developers would expect it to do. Never write code that surprises your readers (in a bad way).
Instead note that you can simply create a TreeSet using Collections.reverseOrder()
for example! In other words: the fact that you defined how to compare two objects of Test
allows you to use a default (reversing) comparator already.
Long story short: avoid "inventing" "clever" tricks to work around framework behavior. Instead, learn how the framework "ticks", and adapt to that. Don't fight the tide, flow with it.