[英]How to switch sorting order in TreeSet
我有一個自定義類,在該類中我已經實現了Comparable
和Comparator
接口。 兩者的排序/比較邏輯相反。
以下面的類為例:
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
}
因此,默認情況下,當我將Test
對象添加到TreeSet
,它是按Comparable
的實現進行排序的,根據JDK源代碼可以理解。 那么是否有任何標志/開關可以切換到Comparable
實現所表示的排序? 我不想將另一個Comparator
傳遞給TreeSet
構造函數。
您的身邊存在一個誤解:
Comparable
類具有可以相互比較的對象(例如,要對其進行排序的容器 Comparator
是比較某個類的兩個對象的東西。 有沒有必要為你讓你的類實現兩者 。
更糟糕的是:請記住,代碼傳達了意圖:您的類實現了兩個接口的想法,但是以“相反”的方式實現,這非常違反直覺 。 它只會使您的讀者感到困惑,並可能導致各種錯誤,僅因為您的代碼所做的事情很少有經驗的Java開發人員會期望這樣做。 切勿編寫使讀者感到驚訝的代碼(不好的方式)。
相反,請注意,您可以簡單地使用例如Collections.reverseOrder()
創建TreeSet! 換句話說:您定義了如何比較Test
兩個對象的事實使您已經可以使用默認的(反向)比較器。
長話短說:避免“發明”“聰明”的技巧來解決框架行為。 相反,學習框架如何“滴答”,並適應它。 不要抗拒潮流,順其自然。
與Comparator
和Comparable
使用相同的對象是非常不典型的。 您可以僅使用兩個接口之一來實現兩個排序順序。
僅使用Comparator
:
//Test implements Comparator. reversed() changes order
new TreeSet(new Test().reversed());
與只是Comparable
:
//elements are Comparable. reverseOrder changes order
new TreeSet(Comparator.reverseOrder());
如果使用Comparator.comparingInt(Test::getField).reversed())
則無需為Test類實現自己的比較方法。
完整的示例代碼:
static class Test {
private int field;
public Test(int field) {
this.field = field;
}
public int getField() {
return field;
}
}
public static void main(String[] args) {
Test test = new Test(5);
Test test2 = new Test(8);
TreeSet<Test> tests = new TreeSet<>(Comparator.comparingInt(Test::getField).reversed());
tests.add(test);
tests.add(test2);
for (Test t:tests)
System.out.println(t.getField());
}
輸出:
8
5
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.