Java Stream interface has two methods findFirst() and findAny() for retrieving elements from streams. Both method looks very much similar but they behave differently in certain conditions. At the high level:
findFirst()
: Returns the first element in the stream.findAny()
: Returns any element from the stream which is useful in parallel processing.
In this post, learn the difference between findFirst() and findAny() methods.
Stream.of("one", "two", "three", "four")
.parallel()
.findFirst()
.ifPresent(System.out::println); // one
Stream.of("one", "two", "three", "four")
.parallel()
.findAny()
.ifPresent(System.out::println); // three - it can change in every run
1. Stream findFirst()
The findFirst() method returns an Optional describing the first element of this stream, when the stream has:
- defined encounter order – first element in encounter order in the stream.
- no encounter order – any element may be returned.
Optional<T> findFirst()
The above assumptions are valid for all sequential and parallel streams and the behavior of findFirst() will not change.
//sequential stream
Stream.of("one", "two", "three", "four")
.findFirst()
.ifPresent(System.out::println);
//parallel stream
Stream.of("one", "two", "three", "four")
.parallel()
.findFirst()
.ifPresent(System.out::println);
Program output.
one
one
2. Stream findAny()
The findAny() method returns an Optional describing any element of a stream, when the Stream has :
- defined encounter order – any element may be returned.
- no encounter order – any element may be returned.
The above theory is valid for all sequential and parallel streams and the behavior of findAny() will not change.
Stream.findAny()
has been introduced for performance gain in the case of parallel streams, only.
Optional<T> findAny()
In non-parallel streams,
findAny()
will return the first element in most of the cases but this behavior is not gauranteed.
//sequential stream
Stream.of("one", "two", "three", "four")
.findAny()
.ifPresent(System.out::println);
//parallel stream
Stream.of("one", "two", "three", "four")
.parallel()
.findAny()
.ifPresent(System.out::println);
Program output.
one
three
3. Differences between findFirst() vs findAny()
In this post, we learned the difference between findFirst()
and findAny()
methods in Java 8 Stream API. Let us quickly summarize the differences:
Feature | findFirst() | findAny() |
---|---|---|
Order Guarantee | Returns the first element in the encounter order of the stream. | May return any element from the stream, not necessarily the first, especially in parallel streams. |
Performance | Might have a performance overhead in parallel streams due to maintaining encounter order. | Can be more efficient in parallel streams since it does not have to maintain encounter order. |
When to Use | Use when the order matters and we need the first element, strictly. | Use when we don’t care which element is returned specially in parallel streams. |
Example Usecases | – Retrieving the first element in a sorted list of transactions to identify the earliest transaction. – Finding the highest priority task from a list of tasks ordered by priority. – Fetching the first log entry from an ordered list to identify the initial state of a system. – Getting the first data point from a time-series dataset to start the analysis. | – Fetching any element from a large dataset processed in parallel to quickly validate the presence of an item. – Choosing any available server from a pool of servers to distribute the load evenly. – Retrieving any sample data point from a large dataset for quick insights without caring about the order. – Picking any element from a population for statistical sampling in data analysis. |
4. Summary
In non-parallel streams, both may return the first element of the stream in most cases but findAny()
does not offer any guarantee of this behavior.
Use findAny()
to get any element from any parallel stream in a faster time. Else we can always use findFirst()
it in most cases.
Reference: Java Stream Interface
Comments