Java 8 Stream -.max() с дубликатами
Итак, у меня есть набор объектов с переменной шага, которая может быть 1 - 4.
public class MyClass {
private Long step;
//other variables, getters, setters, etc.
}
Collection<MyClass> myOjbects = /*get collection*/;
Затем я хотел бы получить один экземпляр MyClass
из коллекции с максимальным значением шага, поэтому я:
final Optional<MyClass> objectWithMaxStep =
myObjects.stream().max(Comparator.comparing(MyClass::getStep));
Однако существуют ситуации, когда в коллекции будет несколько экземпляров MyClass
, которые имеют шаг, равный 4.
Итак, мой вопрос: как определить, какой экземпляр возвращается в Optional
, или он генерирует исключение, когда несколько объектов в потоке сравниваются с максимальным значением?
Документация Java 8 для функции max()
не указывает, что произойдет в этой ситуации.
Ответы
Ответ 1
max
реализовано сокращение коллекции с помощью maxBy
:
public static <T> BinaryOperator<T> maxBy(Comparator<? super T> comparator) {
Objects.requireNonNull(comparator);
return (a, b) -> comparator.compare(a, b) >= 0 ? a : b;
}
Здесь comparator.compare(a, b) >= 0 ? a : b
вы можете видеть, что, когда 2 элемента равны, то есть compare
возвращает 0, тогда возвращается первый элемент. Поэтому в вашем случае сначала будет возвращен объект коллекции MyClass
с наивысшим step
.
UPDATE: Как пользователь the8472, правильно упомянутый в комментариях, вы не должны полагаться на реализацию, которая явно не указана в Javadocs. Но вы можете написать метод unit test on max
, чтобы узнать, изменилась ли эта логика в стандартной java-библиотеке.
Ответ 2
Так как упорядочение не указано в документации, порядок может отличаться в будущих версиях JVM или в разных реализациях JVM.
Если вы заботитесь о том, какой из них возвращается, то мой совет - написать свою собственную операцию сокращения или Collector, чтобы вести себя, как вам хочется. Таким образом, будущие реализации не могут изменить его, и вы можете прямо сказать, что произойдет.