2017-11-02 4 views
6

がストリーム上でfilter()操作の後にNULLポインタ例外をスローする理由がわかりません。この特定のテストケースでは、フィルター操作ですべてが除外され、findAny()の結果は残っていないはずです。JavaストリームfindAny()がfilter()操作ですべてのものを除外した後にnullポインタ例外が発生しました

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()ため、この予想される動作は、nullポインタ例外をスローしますか?

編集:すべての要素を除外するフィルタ操作を解決するための、エレガントで機能的な方法は何ですか?

+3

[なぜfindFirst ()は、最初に見つかった要素がnullの場合、NullPointerExceptionをスローしますか?](https://stackoverflow.com/questions/32466799/why-does-findfirst-throw-a-nullpointerexception-if-the-first-element-it- finds) – alfasin

+1

nullをフィルタリングしたい場合は、答えで述べたように 'filter(Objects :: nonNull)'を使用してください。 – Eugene

答えて

4

NPEを回避する最善の方法は次のとおりです。

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

"AES256".equals(n.textValue()))は、n.textValue()がnullの場合、NPEを投げません。

2

最初にfilterということが混乱していて、filterメソッドがスタックトレースのどこかにあると予想されます。中間処理は何もせず、遅延処理され、端末操作があるときにのみ起動します(例えば、findAny)。実際にはです。スタックトレース(filter method)にはですが、Example.Main.lambda$main$0(Main.java:41)のようになります。

あなたが最初に、null値をフィルタリングする場合:

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

実際にはlambdaはスタックトレースにあります( 'at example.Main.lambda $ main $ 0(Main.java:41)') - 例外がそこにスローされます。 'findAny'はトレース内の最も外側の関数です。 – Cthulhu

+0

@Cthulhu thx、それは私が言ったことです。おむつを交換するのは難しいですし、SO :)は編集します... – Eugene

+0

n.textValue()がnullを返すとどうなりますか? –

0

いいえ、それはストリームに要素が含まれていないとき、動作しません。その場合は代わりにOptional.empty()が返されます。

また、NPEはjavadocsに述べたように、ストリームにおけるNULL値の原因である:

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 
関連する問題