I am little confused between Stream#findAny()
and Stream#findFirst()
of the Stream
API in java 8.
What I understood is that both will return the first matched element from the stream, for example, when used in conjunction with filter?
So, why two methods for same task? Am I missing something?
What I understood is that both will return the first matched element
from the stream, for example, when used in conjunction with filter?
That's not true. According to the javadoc, Stream#findAny()
:
Returns an Optional<T>
describing some element of the stream, or an empty
Optional<T>
if the stream is empty.
The behavior of this operation is explicitly nondeterministic; it is free to select any element in the stream. This is to allow for maximal performance in parallel operations;
while Stream.findFirst()
will return an Optional<T>
describing strictly the first element of the stream. The Stream
class doesn't have a .findOne()
method, so I suppose you meant .findFirst()
.
No, both will not return the first element of the Stream.
From Stream.findAny()
(emphasis mine):
Returns an Optional
describing some element of the stream, or an empty Optional
if the stream is empty.
This is a short-circuiting terminal operation.
The behavior of this operation is explicitly nondeterministic; it is free to select any element in the stream. This is to allow for maximal performance in parallel operations; the cost is that multiple invocations on the same source may not return the same result. (If a stable result is desired, use findFirst()
instead.)
So to put it more simply, it may or may not choose the first element of the Stream.
With the current Oracle specific implementation, I believe that it will return the first element in non-parallel pipeline. However, in a parallel pipeline, it won't always (execute for example System.out.println(IntStream.range(0, 100).parallel().findAny());
, it returned OptionalInt[50]
when I ran it). Anyhow, you must not rely on that.
in parallel mode the findAny
does not guaranteed order, but the findFirst
does.
I wrote some code snippet to show the difference, visit it
findFirst return the first elements of the stream but findAny is free to select any element in the stream.
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
In stream findFirst and findAny return first element and do not execute the rest but in parallelStream, it is not passible to say the order and parallelStream executes the rest of the collection.
Reference
Time 1:25:00