The reason for this is the use of Optional<T> in the return. Optional is not allowed to contain null. Essentially, it offers no way of distinguishing situations "it's not there" and "it's there, but it is set to null".

That's why the documentation explicitly prohibits the situation when null is selected in findFirst():

Throws:

NullPointerException - if the element selected is null

Answer from Sergey Kalinichenko on Stack Overflow
Top answer
1 of 6
96

The reason for this is the use of Optional<T> in the return. Optional is not allowed to contain null. Essentially, it offers no way of distinguishing situations "it's not there" and "it's there, but it is set to null".

That's why the documentation explicitly prohibits the situation when null is selected in findFirst():

Throws:

NullPointerException - if the element selected is null

2 of 6
81

As already discussed, the API designers do not assume that the developer wants to treat null values and absent values the same way.

If you still want to do that, you may do it explicitly by applying the sequence

.map(Optional::ofNullable).findFirst().flatMap(Function.identity())

to the stream. The result will be an empty optional in both cases, if there is no first element or if the first element is null. So in your case, you may use

String firstString = strings.stream()
    .map(Optional::ofNullable).findFirst().flatMap(Function.identity())
    .orElse(null);

to get a null value if the first element is either absent or null.

If you want to distinguish between these cases, you may simply omit the flatMap step:

Optional<String> firstString = strings.stream()
    .map(Optional::ofNullable).findFirst().orElse(null);
System.out.println(firstString==null? "no such element":
                   firstString.orElse("first element is null"));

This is not much different to your updated question. You just have to replace "no such element" with "StringWhenListIsEmpty" and "first element is null" with null. But if you don’t like conditionals, you can achieve it also like:

String firstString = strings.stream()
    .map(Optional::ofNullable).findFirst()
    .orElseGet(()->Optional.of("StringWhenListIsEmpty"))
    .orElse(null);

Now, firstString will be null if an element exists but is null and it will be "StringWhenListIsEmpty" when no element exists.

🌐
GeeksforGeeks
geeksforgeeks.org › java › stream-findfirst-java-examples
Stream findFirst() in Java with examples - GeeksforGeeks
December 26, 2025 - Since the stream is not empty, the first element "Java" is printed. ... Parameters: This method does not take any parameters. Return Value: Returns an Optional<T> containing the first element of the stream and returns an empty Optional if the stream is empty. Example 1: This code demonstrates using Stream.findFirst() to retrieve the first element of a stream, returning an Optional to safely handle empty streams.
🌐
OpenRewrite
docs.openrewrite.org › recipe catalog › java › modernize › java.util apis › use `getfirst()` instead of `stream().findfirst().orelsethrow()`
Use getFirst() instead of stream().findFirst().orElseThrow() | OpenRewrite Docs
import java.util.*; class Foo { void bar(SequencedCollection<String> collection) { String first = collection.stream().findFirst().orElseThrow(); } } import java.util.*; class Foo { void bar(SequencedCollection<String> collection) { String first = collection.getFirst(); } } @@ -5,1 +5,1 @@ class Foo { void bar(SequencedCollection<String> collection) { - String first = collection.stream().findFirst().orElseThrow(); + String first = collection.getFirst(); } This recipe has no required configuration options.
Published   2 weeks ago
🌐
HowToDoInJava
howtodoinjava.com › home › java 8 › java stream findfirst() example
Java Stream findFirst() Example
May 27, 2024 - If Stream has defined encounter order, the findFirst() returns first element in encounter order.
Top answer
1 of 5
33

Well, as for me, the best way is to use functional programing and continue to work with optional. So, for example if you need to pass this string to some service, you can do:

String fisrstString = myList.stream().findFirst().get();
service.doSomething(fisrstString);

But this looks not so good. Instead you can use the pros of functional programing, and do:

myList.stream().findFirst().ifPresent(service::doSomething);
2 of 5
14

You should make use of the Optional returned by findFirst() instead of trying to get its value (if it's actually present).

myList.stream()
    .findFirst()
    .ifPresent(/* consume the string here, if present */);

The Optional.ifPresent method receives a Consumer that will be used only if the Optional contains a non-null value.

The problem is that we Java developers are so used to the imperative paradigm... In particular, we are used to getting an object and pushing it i.e. to a method:

String myString = "hello"; // getting an object here

System.out.println(myString); // pushing the object to System.out here
                              // (via the println method)

With the Optional returned by Stream.findFirst() you were doing the same as above:

String myString = myList.stream()
    .findFirst()
    .get(); // getting a string here

System.out.println(myString); // pushing the string here

On the other hand, the functional paradigm (including Optional) usually works the other way:

myList.stream()
    .findFirst()
    .ifPresent(myString -> System.out.println(myString));

Here, you don't get the string and then push it to some method. Instead, you provide an argument to Optional's ifPresent operation and let the implementation of Optional push the value to your argument. In other words, you pull the value wrapped by the Optional by means of ifPresent's argument. ifPresent will then use this Consumer argument, only if the value is present.

This pull pattern is seen a lot in functional programming and is very useful, once you get used to it. It just requires us developers to start thinking (and programming) in a different way.

🌐
Java2s
java2s.com › Tutorials › Java › Stream_How_to › Stream › Find_first_or_return_somthing_else.htm
Java Stream How to - Find first or return somthing else
//from www. j a v a 2 s .c o m import java.util.Arrays; import java.util.List; public class Main { public static void main(String[] args) { List<String> names = Arrays.asList("HTML", "CSS", "CSS3", "Java", "SQL", "Javascript", "MySQL"); String name5 = names.stream() .map(s -> s.toUpperCase()) .filter(s -> s.length() < 5) .sorted((a, b) -> b.length() - a.length()) .findFirst() .orElse("a"); System.out.println(name5); String name2 = names.stream() .map(s -> s.toUpperCase()) .filter(s -> s.length() < 2) .sorted((a, b) -> b.length() - a.length()) .findFirst() .orElse("Somthing else"); System.out.println(name2); } } Back to Stream ↑
🌐
Jsparrow
jsparrow.github.io › rules › enhanced-for-loop-to-stream-find-first.html
Replace For-Loop with Stream::findFirst | jSparrow Documentation
double defaultValue = -1.0; List<Integer> values = new ArrayList<>(); double defaultIndex = values.stream() .filter(value -> value > 4) .findFirst() .map(Double::valueOf) .orElse(defaultValue);
🌐
ConcretePage
concretepage.com › java › java-8 › java-stream-findfirst
Java Stream findFirst()
Java 8 The findFirst method of Stream finds the first element as Optional in this stream. If stream has no element, findFirst returns empty Optional. If the stream has no encounter order then findFirst may select any element.
Find elsewhere
🌐
Blogger
javarevisited.blogspot.com › 2016 › 03 › how-to-find-first-element-of-stream-in.html
How to find the first element in Stream in Java 8? findFirst() Example
October 5, 2024 - String item = gadgets.stream() .peek(s -> System.out.println("processing: " + s)) .filter(s -> s.length() >8) .findFirst() .orElse(""); Output: processing: SmartPhone result: SmartPhone You can see that filter() has processed just one element from the Stream. Once it found the "SmartPhone", it stops because that satisfies the findFirst() method. Also, it's worth knowing that all intermediate stream operations are lazy (See Java 8 in Action).
🌐
Baeldung
baeldung.com › home › java › java streams › java stream findfirst() vs. findany()
Java Stream findFirst() vs. findAny() | Baeldung
January 9, 2024 - The findFirst() method finds the first element in a Stream. So, we use this method when we specifically want the first element from a sequence. When there is no encounter order, it returns any element from the Stream.
🌐
Java67
java67.com › 2018 › 03 › java-8-stream-find-first-and-filter-example.html
Java 8 Stream filter() + findFirst Example Tutorial | Java67
If you want you can also use the OrElse() method to define a default value just in case Optional is empty. Btw, this is an extremely common code if you have started coding in Java because most of my Java 8 refactoring is replacing the loop with ...
🌐
Medium
medium.com › @satyendra.jaiswal › exploring-short-circuiting-operations-in-java-stream-api-findany-vs-findfirst-698306ec6b92
Exploring Short-Circuiting Operations in Java Stream API: findAny vs. findFirst | by Satyendra Jaiswal | Medium
January 6, 2025 - The Java Stream API has revolutionized the way we work with collections, providing a functional and expressive approach to processing data. Among its many features, short-circuiting operations stand out as powerful tools for efficiency and performance. In this article, we delve into two such operations: findAny and findFirst.
🌐
Scaler
scaler.com › topics › java-stream-findfirst
Java Stream findFirst() - Scaler Topics
Scaler Topics offers free certificate courses for all programming languages like Java, Python, C, C++, DSA etc. Learn from top MAANG experts and level up your skills. Explore now
🌐
Tabnine
tabnine.com › home page › code › java › java.util.stream.stream
java.util.stream.Stream.findFirst java code examples | Tabnine
private static <T> HttpMessageWriter<T> findWriter( BodyInserter.Context context, ResolvableType elementType, @Nullable MediaType mediaType) { return context.messageWriters().stream() .filter(messageWriter -> messageWriter.canWrite(elementType, mediaType)) .findFirst() .map(BodyInserters::<T>cast) .orElseThrow(() -> new IllegalStateException( "No HttpMessageWriter for \"" + mediaType + "\" and \"" + elementType + "\"")); }
🌐
ZetCode
zetcode.com › java › stream-findfirst-findany
Java Stream findFirst/findAny - finding first or any element in Java streams
Main.java · void main() { var words = List.of("war", "cup", "cloud", "alert", "be", "ocean", "book"); var empty = List.of(); var first = words.stream().findFirst().orElse("not found"); System.out.println(first); var first2 = empty.stream().findFirst().orElse("not found"); System.out.println(first2); } We find first elements of the list of words.
🌐
Tabnine
tabnine.com › home page › code › java › java.util.optional
java.util.Optional.orElse java code examples | Tabnine
private static MediaType initDefaultMediaType(List mediaTypes) { return mediaTypes.stream().filter(MediaType::isConcrete).findFirst().orElse(null);
🌐
YouTube
youtube.com › watch
Java 8 - How to use findFirst(), get(), orElse(), orElseGet(), orElseThrow() ? - YouTube
This is a series of java 8 features. In this video, let us understand about few methods in Streams API. Let us learn aboutfindFirst(), get(), orElse(), orEls...
Published   October 29, 2022
🌐
Java67
java67.com › 2018 › 06 › java-8-optional-example-ispresent-orElse-get.html
Java 8 Optional isPresent(), OrElse() and get() Examples | Java67
Anyway, by using the orElse() method we can rewrite the above code as shown below, which is much more cleaner and expressive. /* * Return the first book start with a letter. */ public static String getBook(String letter) { Optional<String> book = listOfBooks.stream() .filter(b -> b.startsWith(letter)) .findFirst(); return book.orElse("Book Not Found"); } You can see that the OrElse() method is much nicer than the combination of isPresent() and get().
🌐
javaspring
javaspring.net › blog › findfirst-java
Java's `findFirst` Method: A Comprehensive Guide — javaspring.net
Instead of getting a NullPointerException, you can use methods like ifPresent, orElse, orElseGet, and orElseThrow to deal with the presence or absence of the element. import java.util.Arrays; import java.util.List; import java.util.Optional; ...