2017-11-02 2 views
6

मुझे यह समझने में परेशानी हो रही है कि 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

संभावित डुप्लिकेट [क्यों ढूँढें फर्स्ट() एक NullPointerException फेंक दें यदि यह पहला तत्व पाता है तो शून्य है?] (https://stackoverflow.com/questions/32466799/why-does-findfirst-throw-a-nullpointerexception-if-the-first-element-it- पाता है) – alfasin

+1

अच्छी तरह से अगर आप नल को फ़िल्टर करना चाहते हैं, तो मैंने जवाब में कहा था कि 'फ़िल्टर (ऑब्जेक्ट्स :: नॉन नल)' का उपयोग करें। – Eugene

उत्तर

4

एनपीई से बचने के लिए सबसे अच्छा तरीका है:

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

इसके अलावा, एनपीई रूप javadocs में कहा गया है, धारा में एक शून्य मान का कारण है

"AES256".equals(n.textValue())) एनपीई फेंक नहीं देगा अगर n.textValue() शून्य है

2

आपका भ्रम इस तथ्य से आता है कि आप filter पहले - और आप filter विधि को स्टैक ट्रेस में कहीं और होने की उम्मीद करेंगे; लेकिन ध्यान दें कि इंटरमीडिएट ऑपरेशंस प्रति-कुछ नहीं करते हैं, उन्हें आलसी तरीके से निष्पादित किया जाता है और जब टर्मिनल ऑपरेशन मौजूद होता है तो केवल तभी लाया जाता है (जैसे आपके मामले में findAny)। यह वास्तव में स्टैक ट्रेस (filter method) में है, लेकिन ऐसा लगता है: Example.Main.lambda$main$0(Main.java:41)

आप शून्य मान फ़िल्टर करना चाहते हैं, तो सबसे पहले कार्य करें:

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

वास्तव में फ़िल्टरिंग लैम्ब्डा स्टैक ट्रेस में है (उदाहरण के लिए। मेन.लैम्ब्डा $ मुख्य $ 0 (Main.java:41) ') - इसलिए अपवाद फेंक दिया गया है। 'findAny' बस ट्रेस में बाहरीतम कार्य होता है। – Cthulhu

+0

@ कथुलु थक्स, यही मेरा मतलब था। एक डायपर बदलने और जवाब देने के लिए मुश्किल है :) संपादित करें ... – Eugene

+0

क्या होता है जब n.textValue() वापस शून्य? –

0

नहीं, यह व्यवहार नहीं है, जब धारा किसी भी तत्व शामिल नहीं है। इस मामले में यह Optional.empty() लौटाता है।

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 
संबंधित मुद्दे