Pages

Saturday, November 21, 2020

Java 8 Stream findFirst() vs findAny() With Examples

1. Overview

In this article, you'll learn what are the differences between findFirst() and findAny() in java 8 Streams.

These methods are quite makes confusion to the some developers.

Let us understand findFirst() vs findAny() first and learn when to use right one.

Read more on :


findAny() and findFirst() are stream terminal operations that means produces the final result.

If any one the stream values is null then it will NullPointerException.
List<String> values = Arrays.asList("A", "B", null, "F", "D");
Optional<String> anyValue = values.stream().findFirst();
Output:
Exception in thread "main" java.lang.NullPointerException
	at java.base/java.util.Objects.requireNonNull(Objects.java:221)
	at java.base/java.util.Optional.<init>(Optional.java:107)
	at java.base/java.util.Optional.of(Optional.java:120)
	at java.base/java.util.stream.FindOps$FindSink$OfRef.get(FindOps.java:194)
	at java.base/java.util.stream.FindOps$FindSink$OfRef.get(FindOps.java:191)
	at java.base/java.util.stream.FindOps$FindTask.doLeaf(FindOps.java:319)
	at java.base/java.util.stream.AbstractShortCircuitTask.compute(AbstractShortCircuitTask.java:115)
	at java.base/java.util.concurrent.CountedCompleter.exec(CountedCompleter.java:746)
	at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:290)
	at java.base/java.util.concurrent.ForkJoinTask.doInvoke(ForkJoinTask.java:408)
	at java.base/java.util.concurrent.ForkJoinTask.invoke(ForkJoinTask.java:736)
	at java.base/java.util.stream.FindOps$FindOp.evaluateParallel(FindOps.java:160)
	at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:233)
	at java.base/java.util.stream.ReferencePipeline.findAny(ReferencePipeline.java:548)
	at com.javaprogramto.java8.streams.find.FindAnyParallelStreamIntegersExample.main(FindAnyParallelStreamIntegersExample.java:15)

2. Understand Usage of Stream.findAny()


By seeing the name of the method, you can assume that it is going to return any value from stream. Yes, you are correct till this point.

But, if you are not worried about the order how the values are appearing in the list or stream.

Syntax:
Optional<T> findAny()

This method returns Optional instance with the value found and returns empty Optional if the stream is empty.
package com.javaprogramto.java8.streams.find;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class FindAnyExample {

	public static void main(String[] args) {

		// creating a list with string values
		List<String> values = Arrays.asList("A", "B", "C", "F", "D");

		// getting the any value from stream.
		Optional<String> anyValue = values.stream().findAny();

		// printing the value
		if (anyValue.isPresent()) {
			System.out.println("Any value from stream : " + anyValue.get());
		} else {
			System.out.println("No value presnt in the stream.");
		}
	}
}

Output:
Any value from stream : A
It has obtained the first value from the stream that is value "A". So, it gets the first value from stream.

Now, the tricky part is if the stream is parallel then it will not return the first value but not guaranteed.

For the same list, called findAny() method on parallel stream.
Optional<String> anyValue = values.stream().parallel().findAny();
Now let us see the output. Look at the below output.
Any value from stream : C
So, the value is changed in case stream is parallel and value cannot be predicted.

Next, let us have a look at another example on parallel stream.
package com.javaprogramto.java8.streams.find;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class FindAnyParallelStreamIntegersExample {

	public static void main(String[] args) {

		// creating a list with integer prime values
		List<Integer> values = Arrays.asList(2, 3, 5, 7, 11);

		// Creating prallel stream.
		Optional<Integer> anyValue = values.stream().parallel().findAny();

		// printing the value
		if (anyValue.isPresent()) {
			System.out.println("Value from integer stream : " + anyValue.get());
		} else {
			System.out.println("No value presnt in the stream.");
		}
	}
}
Output:
Value from integer stream : 5

3. Understand Usage of Stream.findFirst()


As this method name describes, findFirst() method returns the first value from stream for any type of stream it may be sequential or parallel.

This method also returns Optional object with the first value. If the stream is empty then empty Optional is returned.

Let see the examples with sequential and parallel streams.

Sequential Stream:
package com.javaprogramto.java8.streams.find;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class FindFirstSequentialExample {

	public static void main(String[] args) {

		// creating a list with string values
		List<String> values = Arrays.asList("A", "B", "C", "F", "D");

		// Getting the first value from sequential stream using findFirst() method
		Optional<String> anyValue = values.stream().findFirst();

		// printing the value
		if (anyValue.isPresent()) {
			System.out.println("First value from stream : " + anyValue.get());
		} else {
			System.out.println("No value presnt in the stream.");
		}
	}
}
Output:
First value from stream : A

Parallel Stream:
package com.javaprogramto.java8.streams.find;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;

public class FindFirstParallelExample {

	public static void main(String[] args) {

		// creating a list with string values
		List<String> values = Arrays.asList("A", "B", "C", "F", "D");

		// Getting the first value from sequential stream using findFirst() method
		Optional<String> anyValue = values.stream().parallel().findFirst();

		// printing the value
		if (anyValue.isPresent()) {
			System.out.println("First value from parallel stream : " + anyValue.get());
		} else {
			System.out.println("No value presnt in the stream.");
		}
	}
}
Output:
First value from parallel stream : A

From the above two sequential and parallel streams outputs, findFirst() method returns always the same output.

4. Conclusion


In this tutorial, you've seen the all the differences between the findFirst() and findAny() method in java 8.
 
Main similarity is findFirst() and findAny() method returns the first value from the stream if it is sequential. By default, stream is created with sequential pattern. And always both methods returns the same value. if the any value in the stream is null then it will throw NullPointerException.

But, if you working with parallel streams and your intention is to get the first value from stream then use only findFirst() method. But findAny() method works differently with parallel streams and may get any value from stream (mostly first one but not guaranteed).Because, among the parallel threads, which ever thread is started first and what ever the element is picked from the stream is considered as first value.

GitHub


Read Next

No comments:

Post a Comment

Please do not add any spam links in the comments section.