Difference between findAny() and findFirst() in Ja

2019-01-17 09:17发布

问题:

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?

回答1:

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().



回答2:

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.



回答3:

in parallel mode the findAny does not guaranteed order, but the findFirst does.

I wrote some code snippet to show the difference, visit it



回答4:

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


回答5:

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