После прочтения исходного кода, я думаю, должен быть первый величайший элемент, который будет найден в соответствии с порядком сбора. Мы можем проверить исходный код 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
. Поэтому, когда в потоке есть несколько «наибольших/самых низких» элементов, элемент «наибольший/самый низкий» должен быть первым «самым большим/самым низким» элементом в соответствии с порядком сбора
Приведен пример, ваша рекомендация.
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);
Похоже, что не определено поведение. –
Я бы предположил, что это зависит от базовой коллекции. – munyengm
Боковой вопрос: почему это имеет значение? – Tunaki