【问题标题】:findFirst throws java.lang.NullPointerExceptionfindFirst 抛出 java.lang.NullPointerException
【发布时间】:2018-10-15 16:26:26
【问题描述】:

我在下面有这段代码。 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,而且乍一看还不太清楚这些情况是什么。在第一种情况下,它返回一个带有null 元素的stream,它抛出NullPointerException,在第二种情况下,它返回一个可以正常工作的空流。

【问题讨论】:

  • 既然你已经更新了问题,handle exception是否也意味着返回一些值?
  • @nullpointer 我只是在catch 块中记录异常。

标签: java java-8 java-stream optional


【解决方案1】:

您的代码明确返回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");
    

【讨论】:

    【解决方案2】:

    当你这样做时,你认为会发生什么:

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

    i 第一次在哪里是zero?将抛出越界异常 - 您捕获并返回 null;所以你有一个Stream.of(null),你称之为findFirst - 据记录,如果元素为null,则抛出NullPointerException

    【讨论】:

      【解决方案3】:

      来自javadoc for findFirst

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

      Optional 无法区分“存在但为空”和“不存在”

      【讨论】:

        【解决方案4】:

        这是因为您在 map 函数中返回 null。 尝试在map操作后添加.filter(s -&gt; s != null)

        【讨论】:

          猜你喜欢
          • 2013-12-07
          • 1970-01-01
          • 1970-01-01
          • 2020-09-11
          • 1970-01-01
          • 2020-03-07
          • 2016-05-31
          • 1970-01-01
          • 2019-04-13
          相关资源
          最近更新 更多