Разница между findAny() и findFirst() в Java 8
Я немного запутался между Stream#findAny()
и Stream#findFirst()
API Stream
в java 8.
Я понял, что оба возвращают первый согласованный элемент из потока, например, при использовании в сочетании с фильтром?
Итак, почему два метода для одной задачи? Я что-то пропустил?
Ответы
Ответ 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]
, когда я его запускал). Во всяком случае, вы должны не полагаться на это.