I am having trouble figuring why findAny()
throws a null pointer exception after filter()
operation on a stream. In this particular test case, the filter operation should have filtered out everything, leaving no results for findAny()
.
Optional<JsonNode> encryption = sseEncryptionList.stream()
.filter(n -> n.textValue().equals("AES256")) //Filters out everything
.findAny(); //Throws null pointer exception
The stack trace:
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)
Is this expected behavior for findAny()
to throw a null pointer exception if the stream doesn't contain any elements?
Edit: What is an elegant and functional way to resolve filter operations that might filter out all elements?
The best way to avoid NPE is:
Optional<JsonNode> encryption = sseEncryptionList.stream()
.filter(Objects::nonNull)
.filter(n -> "AES256".equals(n.textValue()))
.findAny();
"AES256".equals(n.textValue()))
will not throw NPE if n.textValue() is null
Your confusion comes from the fact that you filter
first - and you would expect the filter
method to be somewhere in the stack trace; but notice that intermediate operations do nothing per-se, they are executed lazily and only kick in when a terminal operation is present (such as findAny
in your case). It's actually there in the stack trace (the filter method
), but it looks like this: Example.Main.lambda$main$0(Main.java:41)
.
If you want to filter null values, first do:
.filter(Objects::nonNull)
.filter(n -> n.textValue().equals("AES256"))
.findAny()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With