[英]findFirst throws java.lang.NullPointerException
I have this code below. 我在下面有这个代码。 The
findfirst
call is throwing NullPointerException
even though I have an orElseGet
call chained 即使我有一个链接的
orElseGet
调用, findfirst
调用也会抛出NullPointerException
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. 我想我们在某些情况下不能显式地返回
null
,并且乍一看这些情况并不十分清楚。 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. 在第一种情况下,它返回一个带有
null
元素的stream
,它抛出NullPointerException
,在第二种情况下,它返回一个工作正常的空流。
Your code is explicitly returning null
您的代码显式返回
null
return null
which thereafter throws NPE, according to the spec of Optional.findFirst
which reads: 根据
Optional.findFirst
的规范,此后抛出NPE,其中包括:
@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). 此外,澄清代码控制甚至无法到达
orElseGet
部分,无论如何假设它在Optional
(无论是空的还是有一些值)上工作。
Few suggestions : 几点建议:
null
explicitly from within an iteration, it seems contradictory to why you'd iterate then. null
,这似乎与你为什么要迭代相矛盾。 Safer side in your code currently , you can filter-in only nonNull objects using filter
as 当前代码中更安全的一面,您可以使用
filter
仅过滤非null对象
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");
What do you think happens when you do: 当你这样做时,你认为会发生什么:
System.out.println(req.substring(numberOfRetry - i));
where i
for the first time is zero
? i
第一次是zero
? An out of bounds exception will be thrown - which you catch and return null
; 将抛出一个越界异常 - 你捕获并返回
null
; so you have a Stream.of(null)
which you call findFirst
on - which is documented to throw that NullPointerException
is case the element is null. 所以你有一个你调用了
findFirst
的Stream.of(null)
- 它被记录为抛出NullPointerException
是元素为null的情况。
From the javadoc for findFirst
: 从
findFirst
的javadoc :
Throws: NullPointerException - if the element selected is null
抛出:NullPointerException - 如果选择的元素为null
Optional
cannot differentiate between "present but null" and "not present" Optional
无法区分“存在但无效”和“不存在”
It happens because you return null
in your map function. 这是因为您在map函数中返回
null
。 Try to add .filter(s -> s != null)
after map
operation. 尝试在
map
操作后添加.filter(s -> s != null)
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.