如何链接和应用比较器流?

jac*_*ack 9 java java-8 java-stream

我有一系列未分类的项目和一组比较器.我想通过使用"thenComparing"(Multisort)将所有比较器应用到流中.是否有比以下代码更优雅的方式来实现这一点?

Stream unsorted = ...;
Stream<Comparator> comparators = ...;

Comparator compareFunc = comparators.reduce(null, (a, b) -> {
        if(a == null) {
            return b;
        }else {
            return  a.thenComparing(b); 
        }

    });

Stream result = unsorted.sorted(compareFunc);
Run Code Online (Sandbox Code Playgroud)

Hol*_*ger 7

不要对s 使用标识值Comparator.如果comparators流是空的(即不包含任何内容Comparator),则不应该排序:

Stream result=comparators.reduce(Comparator::thenComparing)
             .map(unsorted::sorted).orElse(unsorted);
Run Code Online (Sandbox Code Playgroud)

请注意,如果comparators流只包含一个Comparator,那Comparator将是减少的结果.


传递给方法的参考Optional.map可能需要一些经验才能适应它.因此,使用更详细的lambda语法来显示正在发生的事情可能是值得的:

Stream<String> result=comparators.reduce(Comparator::thenComparing)
    .map((comparator) -> unsorted.sorted(comparator)).orElse(unsorted);
Run Code Online (Sandbox Code Playgroud)

这是编程风格或个人偏好的问题,可能会随着时间而改变.


ass*_*ias 5

使用Mark Peters的建议并将其与方法参考混合,您可以这样编写比较器:

Comparator compareFunc = comparators.reduce((a, b) -> 0, Comparator::thenComparing);
Run Code Online (Sandbox Code Playgroud)

或者从Holger那里偷一点:

Optional<Comparator> compareFunc = comparators.reduce(Comparator::thenComparing);
Stream<?> result = compareFunc.isPresent() ? result.sorted(compareFunc.get())
                                           : unsorted;
Run Code Online (Sandbox Code Playgroud)

  • @Holger我偷了你的一些想法 - 我发现你的答案的反转语法不太清楚,说实话. (2认同)