在filter()操作过滤掉所有内容后,Java流findAny()遇到空指针异常

时间:2017-11-02 18:08:38

标签: java java-8 java-stream

我无法确定findAny()在流上filter()操作后抛出空指针异常的原因。在此特定测试用例中,过滤器操作应该已过滤掉所有内容,但不会为findAny()留下任何结果。

Optional<JsonNode> encryption = sseEncryptionList.stream()
                  .filter(n -> n.textValue().equals("AES256")) //Filters out everything
                  .findAny(); //Throws null pointer exception

堆栈跟踪:

Exception in thread "main" java.lang.NullPointerException
at example.Main.lambda$main$0(Main.java:41)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:174)
at java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1351)
at java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:126)
at java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:498)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:485)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.FindOps$FindOp.evaluateSequential(FindOps.java:152)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.findAny(ReferencePipeline.java:469)
at example.Main.main(Main.java:42)

如果流不包含任何元素,findAny()的预期行为是否会抛出空指针异常?

编辑:解析可能过滤掉所有元素的过滤操作的优雅且实用的方法是什么?

3 个答案:

答案 0 :(得分:8)

避免NPE的最佳方法是:

Optional<JsonNode> encryption = sseEncryptionList.stream()
              .filter(Objects::nonNull)
              .filter(n -> "AES256".equals(n.textValue()))
              .findAny();
如果n.textValue()为null,

"AES256".equals(n.textValue()))将不会抛出NPE

答案 1 :(得分:3)

您的混淆来自于您filter首先 - 并且您希望filter方法位于堆栈跟踪中的某个位置;但请注意,中间操作本身不执行任何操作,它们是懒惰执行的,只有在存在终端操作时才会启动(例如在您的情况下为findAny)。它在堆栈跟踪(filter method)中实际上是那里,但它看起来像这样:Example.Main.lambda$main$0(Main.java:41)

如果要过滤空值,请首先执行:

.filter(Objects::nonNull)
.filter(n -> n.textValue().equals("AES256"))
.findAny()

答案 2 :(得分:1)

不,当流不包含任何元素时,不是行为。在这种情况下,它会返回Optional.empty()

此外,NPE是流中空值的原因,如javadocs中所述:

Returns:
an Optional describing some element of this stream, or an empty Optional if the stream is empty

Throws:
NullPointerException - if the element selected is null