虽然我怀疑答案是"未指定" ...
如果有多个"最大/最低" Stream
传递给max或min方法的Comparator
认为相等(返回0
)的元素,是指定哪个元素会被找到?
答案 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 matter的Brian Goetz对于流API具有相当的权威性:
如果对流进行排序(例如从数组或List获取的流),则返回第一个元素,该元素在多个最大元素的情况下最大;只有当流是无序的时,才允许选择任意元素。
遗憾的是,在Stream.max
的文档中没有做出这样明确的陈述,但至少它符合我们对实施的经验和知识(those of us who looked at the source code)。不要忘记,实际考虑,因为如果unordered().max(comparator)
被允许,通过max
通过Topics
与当前状态说“选择任何而不是第一”比说“先选而不是任何”更容易首先选择一个任意元素。