我在下面有此代码。
即使我有一个findfirst
链接的电话,NullPointerException
调用仍会抛出orElseGet
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");
但是,如果我按如下所示进行过滤调用,则效果很好:
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");
我猜我们在某些情况下不能显式返回null
,而且乍一看不清楚这些情况是什么。在第一种情况下,它返回其中包含stream
元素的null
并引发NullPointerException
,在第二种情况下,它返回正常工作的空流。
答案 0 :(得分:5)
您的代码明确返回了null
return null
此后根据Optional.findFirst
的规范将NPE抛出:
@throws NullPointerException if the element selected is null Optional<T> findFirst();
另外,为了澄清代码控制,甚至无法到达orElseGet
部分,而该部分肯定可以在Optional
上工作(为空或有一定值)。
一些建议:
null
,这似乎与您为什么要进行迭代如此矛盾。当前在代码中更安全的一面 ,您只能使用filter
作为
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");
答案 1 :(得分:3)
您认为这样做时会发生什么:
System.out.println(req.substring(numberOfRetry - i));
i
第一次在哪里zero
?将引发超出范围的异常-您捕获并返回null
;因此您有一个Stream.of(null)
,您将其称为findFirst
-据记载,如果元素为null,则抛出NullPointerException
。
答案 2 :(得分:2)
抛出: NullPointerException-如果所选元素为null
ABC0123-> Not Valid.
XYZ002456789->Not Valid.
ABC123->Valid
ABC1->Valid
不能区分“存在但为空”和“不存在”
答案 3 :(得分:2)
发生这种情况是因为您在地图函数中返回了null
。
尝试在.filter(s -> s != null)
操作之后添加map
。