首页 > 解决方案 > 如何在 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到 a时,它会按照 JDK 源代码的实现进行排序。那么是否有任何标志/开关可以切换到实现所代表的排序?我不想将另一个传递给构造函数。TreeSetComparableComparableComparatorTreeSet

标签: java

解决方案


你有一个误解:

  • 一个Comparable类具有可以相互比较的对象(例如,通过一个想要对它们进行排序的容器
  • AComparator是比较某个类的两个对象的东西。

你不需要让你的类同时实现。

更糟糕的是:请记住代码传达意图:您的类实现两个接口的想法,但是以“相反”的方式,这非常违反直觉。它只会让您的读者感到困惑,并可能导致各种错误,因为您的代码做了一些经验丰富的 Java 开发人员会期望它做的事情。永远不要编写让读者感到惊讶的代码(以一种糟糕的方式)。

请注意,您可以简单地使用Collections.reverseOrder()例如创建一个 TreeSet!换句话说:您定义了如何比较两个对象的事实Test允许您已经使用默认(反向)比较器。

长话短说:避免“发明”“聪明”的技巧来解决框架行为。相反,学习框架如何“滴答作响”,并适应它。不与潮流搏斗,随波逐流。


推荐阅读