在 Java 8 中反转比较器

Posted

技术标签:

【中文标题】在 Java 8 中反转比较器【英文标题】:Reverse a comparator in Java 8 【发布时间】:2016-01-04 21:09:19 【问题描述】:

我有一个 ArrayList 并希望按降序对其进行排序。我使用它java.util.stream.Stream.sorted(Comparator) 方法。下面是根据 Java API 的描述:

返回一个由该流的元素组成的流,按照提供的Comparator排序。

这个方法返回一个升序排序。我应该更改哪个参数,只是为了降序?

【问题讨论】:

当然要更改比较器的行为。 【参考方案1】:

您可以使用Comparator.reverseOrder() 让比较器提供与自然顺序相反的顺序。

如果您想反转现有比较器的顺序,可以使用Comparator.reversed()

示例代码:

Stream.of(1, 4, 2, 5)
    .sorted(Comparator.reverseOrder()); 
    // stream is now [5, 4, 2, 1]

Stream.of("foo", "test", "a")
    .sorted(Comparator.comparingInt(String::length).reversed()); 
    // stream is now [test, foo, a], sorted by descending length

【讨论】:

【参考方案2】:

您也可以使用Comparator.comparing(Function, Comparator) 必要时链接比较器很方便,例如:

Comparator<SomeEntity> ENTITY_COMPARATOR = 
        Comparator.comparing(SomeEntity::getProperty1, Comparator.reverseOrder())
        .thenComparingInt(SomeEntity::getProperty2)
        .thenComparing(SomeEntity::getProperty3, Comparator.reverseOrder());

【讨论】:

比较器 ENTITY_COMPARATOR = Comparator.comparing(SomeEntity::getProperty1, reverseOrder()) 如果您要对多个属性进行排序,并且只想反转其中一些属性,此示例非常有用!【参考方案3】:

Java 8 Comparator 接口有一个reversed 方法:https://docs.oracle.com/javase/8/docs/api/java/util/Comparator.html#reversed--

【讨论】:

【参考方案4】:

当你有一个自定义比较器并且反向是有条件的(你可以做也可以不做)时,我发现这个问题是为了反转顺序。

皮诺曹提出的想法帮助了我。

代码如下:

int order = requestedOrder.equals("asc") ? 1 : -1;

Collections.sort(List<CustomObj>, new Comparator<CustomObj>() 
    public int compare(CustomObj first, CustomObj scnd) 
        return first.getComparableParam().compareTo(scnd.getComparableParam()) * order;
    
);

希望以后能帮到别人

【讨论】:

让我们希望compareTo 永远不会返回Integer.MIN_VALUE(因为Integer.MIN_VALUE * -1 == Integer.MIN_VALUE,也就是说,没有任何改变)-为了反转结果最好交换两个值scnd.getComparableParam().compareTo(first.getComparableParam())【参考方案5】:

为什么不扩展现有的比较器并覆盖 super and nor 结果。 Comperator 接口的实现并不重要,但它更清楚地说明了发生了什么。

结果你得到一个简单的可重用类文件、可测试的单元步骤和清晰的 javadoc。

public class NorCoperator extends ExistingComperator implements Comparator<MyClass> 
    @Override
    public int compare(MyClass a, MyClass b) throws Exception 
        return super.compare(a, b)*-1;
    

【讨论】:

以上是关于在 Java 8 中反转比较器的主要内容,如果未能解决你的问题,请参考以下文章

java 在java 8中排序比较器

java Collections 工具类

如何使用流 API 反转比较器顺序? [复制]

如果堆栈在数字较低的地址处增长,为啥指针比较会反转呢?

设计模式之美——依赖反转原则

设计模式之美——依赖反转原则