Stream.max()如何处理相等?

时间:2016-04-19 07:47:20

标签: java java-8 java-stream

虽然我怀疑答案是"未指定" ...

如果有多个"最大/最低" Stream传递给maxmin方法的Comparator认为相等(返回0)的元素,是指定哪个元素会被找到?

2 个答案:

答案 0 :(得分:5)

阅读源代码后,我认为应该是根据集合顺序找到的第一个最大的元素。 我们可以查看Stream.max(Comparator<? super T> comparator)的源代码,实现类是ReferencePipeline.max

    @Override
    public final Optional<P_OUT> max(Comparator<? super P_OUT> comparator) {
        return reduce(BinaryOperator.maxBy(comparator));
    }

您可以看到,当您致电Stream.max时,您的意思是拨打Stream.reduce(BinaryOperator<P_OUT> accumulator)

查看BinaryOperator.maxBy(comparator)

的源代码
    public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
        Objects.requireNonNull(comparator);
        return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
    }

很明显,当a等于b时,它会返回a。因此,当Stream中有多个“最大/最低”元素时,“最大/最低”元素应该是根据集合顺序的第一个“最大/最低”元素

有一个吹嘘的例子,仅供参考。

        List<Student> list = Arrays.asList(new Student("s1", 1), new Student("s2", 5), new Student("s3", 3), new Student("s4", 5));
        // it should be student of 's2'
        list.stream().max(Comparator.comparing(Student::getScore));
        // it should be student of 's4'
        list.stream().reduce((a, b) -> Comparator.comparing(Student::getScore).compare(a, b) > 0 ? a : b);

答案 1 :(得分:5)

确实很难从文档中提取明确的陈述。如果我们试图从“减少”过程的一般描述和文档的类似提示中得出结论,那么我们总觉得我们可能做了太多的解释。

但是,来自explicit statement regarding this matterBrian Goetz对于流API具有相当的权威性:

  

如果对流进行排序(例如从数组或List获取的流),则返回第一个元素,该元素在多个最大元素的情况下最大;只有当流是无序的时,才允许选择任意元素。

遗憾的是,在Stream.max的文档中没有做出这样明确的陈述,但至少它符合我们对实施的经验和知识(those of us who looked at the source code)。不要忘记,实际考虑,因为如果unordered().max(comparator)被允许,通过max通过Topics与当前状态说“选择任何而不是第一”比说“先选而不是任何”更容易首先选择一个任意元素。