簡體   English   中英

如何在TreeSet中切換排序順序

[英]How to switch sorting order in TreeSet

我有一個自定義類,在該類中我已經實現了ComparableComparator接口。 兩者的排序/比較邏輯相反。

以下面的類為例:

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兩個對象的事實使您已經可以使用默認的(反向)比較器。

長話短說:避免“發明”“聰明”的技巧來解決框架行為。 相反,學習框架如何“滴答”,並適應它。 不要抗拒潮流,順其自然。

ComparatorComparable使用相同的對象是非常不典型的。 您可以僅使用兩個接口之一來實現兩個排序順序。

僅使用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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM