I have this code below.
The findfirst
call is throwing NullPointerException
even though I have an orElseGet
call chained
int numberOfRetry = 5;
String req = "abc";
String res =
Stream.iterate(0, n -> n + 1).map(i -> {
try {
return req.substring(numberOfRetry - i);
} catch (Exception e) {
// log exception
}
return null;
})
.limit(1)
.findFirst()
.orElseGet(() -> "Exception");
However, it works fine if I put a filter call as shown below:
int numberOfRetry = 5;
String req = "abc";
String res =
Stream.iterate(0, n -> n + 1).map(i -> {
try {
return req.substring(numberOfRetry - i);
} catch (Exception e) {
// log exception
}
return null;
})
.limit(1)
.filter(Objects::nonNull)
.findFirst()
.orElseGet(() -> "Exception");
I guess we cannot explicitly return null
in some situations, and it is not quite clear what those situations are at first glance. In the first case it returns a stream
with the null
element in it which throws NullPointerException
, in the second case it returns an empty stream which works fine.
Java 8 introduced an Optional class which is a nicer way to avoid NullPointerExceptions. You can use Optional to encapsulate the potential null values and pass or return it safely without worrying about the exception. Without Optional, when a method signature has return type of certain object.
The findAny() method returns any element from a Stream, while the findFirst() method returns the first element in a Stream.
Stream findFirst() in Java with examples Stream findFirst() returns an Optional (a container object which may or may not contain a non-null value) describing the first element of this stream, or an empty Optional if the stream is empty. If the stream has no encounter order, then any element may be returned.
Your code is explicitly returning null
return null
which thereafter throws NPE, according to the spec of Optional.findFirst
which reads:
@throws NullPointerException if the element selected is null Optional<T> findFirst();
Also, to clarify the code control couldn't even reach the orElseGet
part which anyway assumingly works over an Optional
(either empty or with some value).
Few suggestions :
null
explicitly from within an iteration, it seems contradictory to why you'd iterate then.Safer side in your code currently, you can filter-in only nonNull objects using filter
as
Stream.iterate(0, n -> n + 1).map(i -> {
try {
return req.substring(numberOfRetry - i);
} catch (Exception e) {
err.add(e);
}
return null;
})
.filter(Objects::nonNull)
.limit(1)
.findFirst()
.orElse("Exception");
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