适用于多种条件的Collections.sort

pro*_*bie 1 java sorting comparator

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

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

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

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

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

Sam*_*ipp 6

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

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

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

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();
    }
});
Run Code Online (Sandbox Code Playgroud)

  • @ OleV.V。另一个联系是,lambda和流都是在Java 8中引入的,这是OP在流解决方案中遇到的问题。 (2认同)
  • @ OleV.V。另一个更正,他对lambda解决方案没有问题,但是对Comparator.comparing解决方案(Java 8中也引入了)没有问题。同样,“ Lambda”也不够用,因为我们正在注释的答案使用方法引用而不是lambda参数化了Comparator.comparing。 (2认同)
  • 不要使用减号来实现比较器。`a.getInt() - b.getInt()` 可能会溢出。使用 Integer.compare(a.getInt(), b.getInt())`。在比较器链接的情况下,您可以使用更简单的“thenComparingInt(MyObject::getInt)”而不是“thenComparing((a, b) -&gt; a.getInt() - b.getInt())”。 (2认同)