适用于多种条件的Collections.sort

时间:2019-03-14 13:13:37

标签: java sorting comparator

我有一个要排序的对象列表。但是我有三个不同的条件。这就是为什么我有以下代码:

Collections.sort(myList, new Comparator<MyObject>() {
    @Override
    public int compare(MyObject o1, MyObject o2) {
        // my code
    }
});

三遍。首先将条件为x的所有元素排序到列表的底部。然后第二次将条件为y的所有元素排序到底部,并再次对条件z进行排序。

现在我想知道如何在一个比较方法中组合多个条件。因此,我不必三遍。

编辑:要进一步了解条件。我想将所有具有条件x的对象排序到列表的底部。如果元素满足条件y,则该元素应甚至低于x,并且对z也适用。

3 个答案:

答案 0 :(得分:5)

您可以使用Java Streams。在使用Collection.sortdocs)时也会使用此方法:

myList.sort(Comparator.comparing(MyObject::getAttributeX)
    .thenComparing(i -> i.getSomething().getSubValue())
    .thenComparing((a, b) -> a.getInt() - b.getInt()));

如果使用较低版本的Java 8,则必须自己在比较器中实现排序逻辑或使用外部库:

Collections.sort(myList, new Comparator<MyObject>() {
    @Override
    public int compare(MyObject a, MyObject b) {
        int cmp0 = a.getAttributeX().compareTo(b.getAttributeX());
        if (cmp0 != 0) {
            return cmp0;
        }
        int cmp1 = a.getSomething().getSubValue().compareTo(b.getSomething().getSubValue());
        if (cmp1 != 0) {
            return cmp0;
        }
        return a.getInt() - b.getInt();
    }
});

答案 1 :(得分:2)

我假设0, 2, 4具有类似的方法

MyObject

然后以这种方式最简单的排序:

public boolean isX() {
    return // either false or true;
}

由于 Collections.sort(myList, Comparator.comparing(MyObject::isX) .thenComparing(MyObject::isY) .thenComparing(MyObject::isZ)); 等返回isX值,因此这些值被排序,booleanfalse之前。因此,排序将确保满足x条件(true返回true)的所有对象都将出现在列表的末尾。在其余对象中,满足y的对象将最后移动,恰好在x-s之前。对于z同样。

如果x,y和z由类中进行排序的方法确定怎么办?在此示例中,我们将其称为isX类。这样的方法可能看起来像:

Sorter

您需要做的就是将public static boolean isY(MyObject obj) { return // either false or true; } 替换为MyObject::isX

Sorter::isX

您也可以在 Collections.sort(myList, Comparator.comparing(Sorter::isX) .thenComparing(Sorter::isY) .thenComparing(Sorter::isZ)); 中混合使用一些方法,在Sorter中定义一些方法。

真正发生的是将返回的MyMethod值放入boolean对象中,然后将它们进行比较,但是您不必担心此细节。

编辑:较低的Android API版本:

Boolean

它甚至保存上述自动装箱。

答案 2 :(得分:0)

例如,您可以使用比较链:

   public int compareTo(Foo that) {
     return ComparisonChain.start()
         .compare(this.aString, that.aString)
         .compare(this.anInt, that.anInt)
         .compare(this.anEnum, that.anEnum, Ordering.natural().nullsLast())
         .result();
   }

参见此处:link to docs