Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How return null by using Stream API?

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?

like image 299
Roman Shmandrovskyi Avatar asked Jul 27 '18 13:07

Roman Shmandrovskyi


People also ask

Will stream collect 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.

How do you null a check in stream?

We can use lambda expression str -> str!= null inside stream filter() to filter out null values from a stream.

Does stream throw null pointer exception?

Creating Streams From CollectionsWhen the provided collection points to a null reference, the code will throw a NullPointerException at runtime.

How do I check if a stream is not null?

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.


3 Answers

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

like image 163
Eugene Avatar answered Sep 19 '22 10:09

Eugene


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.

like image 43
ernest_k Avatar answered Sep 21 '22 10:09

ernest_k


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));
like image 33
Nikolas Charalambidis Avatar answered Sep 20 '22 10:09

Nikolas Charalambidis