繁体   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