Я понял, что оба будут возвращать первый совпавший элемент из потока, например, при использовании вместе с фильтром?
Это не правда. Согласно javadoc Stream#findAny()
:
Возвращает Optional<T>
описание некоторого элемента потока или пустое значение,
Optional<T>
если поток пуст. Поведение этой операции явно недетерминировано; Вы можете выбрать любой элемент в потоке. Это сделано для обеспечения максимальной производительности при параллельных операциях;
while Stream.findFirst()
вернет строгоOptional<T>
описывающий первый элемент потока. У класса нет метода, значит, вы имели в виду .Stream
.findOne()
.findFirst()
filter
применяется,findAny
может вернуть любой элемент, в том числе , что не соответствует фильтр применяется?findAny
может возвращаться любой элемент из этого (вроде) случайным образом, особенно при параллельных потоковых операцияхНет, оба не вернут первый элемент Stream.
Из
Stream.findAny()
(выделено мной):Поведение этой операции явно недетерминировано; Вы можете выбрать любой элемент в потоке . Это сделано для обеспечения максимальной производительности при параллельных операциях; цена заключается в том, что несколько вызовов одного и того же источника могут не возвращать один и тот же результат. (Если желателен стабильный результат, используйте
findFirst()
.)Проще говоря, он может выбрать или не выбрать первый элемент Stream.
Я считаю, что с текущей реализацией, специфичной для Oracle, она вернет первый элемент в непараллельном конвейере. Однако в параллельном конвейере это не всегда, например, выполнение
System.out.println(IntStream.range(0, 100).parallel().findAny());
он вернулся,
OptionalInt[50]
когда я его запустил. Во всяком случае, вы не должны полагаться на это.источник
findFirst возвращает первые элементы потока, но findAny может выбрать любой элемент в потоке.
List<String> lst1 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya"); List<String> lst2 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya"); Optional<String> findFirst = lst1.parallelStream().filter(s -> s.startsWith("D")).findFirst(); Optional<String> fidnAny = lst2.parallelStream().filter(s -> s.startsWith("J")).findAny(); System.out.println(findFirst.get()); //Always print David System.out.println(fidnAny.get()); //Print Jack/Jill/Julia :behavior of this operation is explicitly nondeterministic
источник
в параллельном режиме
findAny
не гарантируется порядок, ноfindFirst
.Я написал фрагмент кода, чтобы показать разницу, посетите его
источник
В потоках findFirst и findAny возвращают первый элемент и не выполняют остальные, но в parallelStream невозможно указать порядок, а parallelStream выполняет оставшуюся часть коллекции.
Справка
Время 1:25:00
источник
Скажу лишь, что остерегайтесь
findFirst()
ИfindAny()
при использовании.Как видно из их Javadoc ( здесь и здесь ), оба метода возвращают произвольный элемент из потока - если поток не имеет порядка встречи , и в этом случае
findFirst()
возвращается первый элемент, аfindAny()
вернет любой элемент.Предположим, у нас есть заказ,
list
состоящий из ISBN и имени КНИГИ. В качестве сценария посмотрите этот пример:public class Solution { private Integer ISBN; private String BookName; public Solution(int i, String string) { ISBN =i; BookName = string; } //getters and setters }
public static void main(String[] args) { List<Solution> Library = Arrays.asList(new Solution(12,"Java in Action"),new Solution(13,"Java 8"),new Solution(15,"Java 8 Features"),new Solution(16,"Java in Action")); System.out.println(Library.stream() .map(p->p.getBookName()) .sorted(Comparator.reverseOrder()) .findFirst()); }
Выход :
Optional[Java in Action]
Могут быть сценарии, когда название книги совпадает, но номера ISBN разные, в этом случае сортировка и поиск книги могут быть очень похожи
findAny()
и дадут неверный результат. Подумайте о сценарии, в котором 5 книг названы «Справочник по Java», но имеют разные номера ISBN, иfindFirst()
книга по названию будет иметь такой же результатfindAny()
.Подумайте о сценарии, в котором:
ISBN Name Of book +-----+------------------+ | 100 | Java-8 in Action | +-----+------------------+ | 101 | Java-8 in Action | +-----+------------------+ | 102 | Java-8 in Action | +-----+------------------+ | 103 | Java-8 in Action | +-----+------------------+ | 104 | Java-8 in Action | +-----+------------------+
здесь findFirst () и findAny () дадут одинаковый результат, даже если они отсортированы по BookByName.
Подробная статья:
источник
Когда
Stream
неупорядочено,findFirst()
иfindAny()
такие же. Но когдаStream
заказывают,findAny()
будет лучше.источник
Stream
«заказанным»? Он всегда упорядочен (операции выполняются в заданномStream
порядке каждый раз, когда он не распараллеливается), но, возможно, не сортируется пользователем.