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

Разница между findAny() и findFirst() в Java 8

Я немного запутался между Stream#findAny() и Stream#findFirst() API Stream в java 8.

Я понял, что оба возвращают первый согласованный элемент из потока, например, при использовании в сочетании с фильтром?

Итак, почему два метода для одной задачи? Я что-то пропустил?

4b9b3361

Ответ 1

Я понял, что оба возвращают первый согласованный элемент из потока, например, при использовании в сочетании с фильтром?

Это не так. Согласно javadoc, Stream#findAny():

Возвращает Optional<T>, описывающий некоторый элемент потока, или пустой Optional<T>, если поток пуст. Поведение этой операции явно недетерминировано; можно свободно выбирать любой элемент в потоке.. Это позволяет обеспечить максимальную производительность при параллельных операциях;

while Stream.findFirst() вернет Optional<T>, описывающий строго первый элемент потока. Класс Stream не имеет метода .findOne(), поэтому, полагаю, вы имели в виду .findFirst().

Ответ 2

Нет, оба не возвратят первый элемент потока.

От Stream.findAny() (внимание мое):

Возвращает Optional, описывающий некоторый элемент для потока или пустой Optional, если поток пуст.

Это операция короткого замыкания.

Поведение этой операции явно недетерминировано; можно выбрать любой элемент в потоке. Это должно обеспечить максимальную производительность при параллельных операциях; стоимость состоит в том, что несколько вызовов в одном источнике могут не возвращать тот же результат. (Если требуется стабильный результат, используйте вместо него findFirst().)

Итак, проще говоря, он может или не может выбрать первый элемент Stream.

С текущей реализацией Oracle я считаю, что он вернет первый элемент в непараллельный конвейер. Однако в параллельном конвейере он не всегда (например, System.out.println(IntStream.range(0, 100).parallel().findAny());, он возвращал OptionalInt[50], когда я его запускал). Во всяком случае, вы должны не полагаться на это.