findFirst抛出java.lang.NullPointerException

时间:2018-10-15 16:26:27

标签: java java-8 java-stream optional

我在下面有此代码。 即使我有一个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,在第二种情况下,它返回正常工作的空流。

4 个答案:

答案 0 :(得分:5)

您的代码明确返回了null

return null

此后根据Optional.findFirst的规范将NPE抛出:

@throws NullPointerException if the element selected is null
Optional<T> findFirst();

另外,为了澄清代码控制,甚至无法到达orElseGet部分,而该部分肯定可以在Optional上工作(为空或有一定值)。


一些建议:

  • 不要忽略异常,尤其是当您从所有异常中找出最普通的异常时。
  • 避免在迭代中显式返回null,这似乎与您为什么要进行迭代如此矛盾。
  • 当前在代码中更安全的一面 ,您只能使用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");
    

答案 1 :(得分:3)

您认为这样做时会发生什么:

System.out.println(req.substring(numberOfRetry - i));

i第一次在哪里zero?将引发超出范围的异常-您捕获并返回null;因此您有一个Stream.of(null),您将其称为findFirst-据记载,如果元素为null,则抛出NullPointerException

答案 2 :(得分:2)

来自javadoc for findFirst

  

抛出:       NullPointerException-如果所选元素为null

ABC0123-> Not Valid. XYZ002456789->Not Valid. ABC123->Valid ABC1->Valid 不能区分“存在但为空”和“不存在”

答案 3 :(得分:2)

发生这种情况是因为您在地图函数中返回了null。 尝试在.filter(s -> s != null)操作之后添加map

相关问题