So, I have an ArrayList
of autogenerated strings. I want to find the first element that contains some character or else if there is no one element that matches this filter, to apply another filter. In another way, I want to return null
object.
So I write this lambda expression:
str.stream()
.filter(s -> s.contains("q"))
.findFirst()
.orElseGet(() -> str.stream()
.filter(s -> s.contains("w"))
.findFirst()
.orElseGet(null))
But if there is no one element that matches this two filters I will have NullPointerException. How, can I get something like: return null
?
So as long as you don't do weird things like combine function return null , the Collector always return at least a mutable container using your provided supplier function.
We can use lambda expression str -> str!= null inside stream filter() to filter out null values from a stream.
Creating Streams From CollectionsWhen the provided collection points to a null reference, the code will throw a NullPointerException at runtime.
1.1 Java Stream Filter or using the static nonNull() method provided by the java. util. Objects class. This method returns true if the allocated reference is not null, otherwise false.
Unless I'm missing something obvious, simply .orElse(null)
instead of the last orElseGet
. orElseGet
accepts a Supplier
and you pass a null
, calling get()
on a null reference, well...
An additional, simpler approach: you can filter on strings containing q
or w
, then sort to move those containing q
first, find first, return null if the optional is empty:
str.stream()
.filter(s -> s.contains("q") || s.contains("w"))
.sorted((s1, s2) -> s1.contains("q") ? -1 : 1 )
.findFirst()
.orElse(null);
.sorted((s1, s2) -> s1.contains("q") ? -1 : 1 )
will move the strings containing "q"
first. Since the stream has been filtered only on values containing either q
or w
, then returning null will only happen no element is retained.
The problem is Optional::orElseGet(null)
which accepts a Supplier<T>
and throws the NullPointerException
.
Use the Optional::orElse(null)
which accepts T
which is String
in your case.
The following code works:
List<String> str = Arrays.asList("a", "b", "c");
String output = str.stream()
.filter(s -> s.contains("q"))
.findFirst()
.orElseGet(() -> str.stream()
.filter(s -> s.contains("w"))
.findFirst()
.orElse(null)); // <-- HERE
System.out.println(output); // Prints null
Alternatively, use the Optional::orElseGet(Supplier<? extends T> other)
to return null
. The Supplier
itself must be not null
:
.orElseGet(() -> null));
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With