我无法确定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()
的预期行为是否会抛出空指针异常?
编辑:解析可能过滤掉所有元素的过滤操作的优雅且实用的方法是什么?
答案 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