Подтвердить что ты не робот

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() не указывает, что произойдет в этой ситуации.

4b9b3361

Ответ 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, чтобы вести себя, как вам хочется. Таким образом, будущие реализации не могут изменить его, и вы можете прямо сказать, что произойдет.