2016-12-04 280 views
2

我试图访问内部对象而不引起空指针异常。 如果条件null检查并使用利用java 8功能,我想避免手动编写。Java 8 stream findFirst throwing NPE,无法过滤掉流中的非空对象

我正在从findFirst方法获取Nullpointer异常。我知道,findFirst返回空指针异常,如果选定的元素为空,所以我试图在调用findFirst之前使用过滤器(对象:: nonNull)过滤掉空对象,但它仍然抛出空指针。

看起来像我的过滤不起作用,但我不知道为什么。

Please find below the code 

package main.java; 

import java.util.*; 
import java.util.stream.Stream; 


public class OptionalTest { 

    public static void main(String args[]) { 
     Inner in = new Inner("Has Value"); 
     Nested nest = new Nested(in); 
     List<Nested> list = new ArrayList<Nested>(); 
     //list.add(nest); //commented out to test failure scenario 
     list.add(null); //added null 
     list.add(null); //added null 
     Outer outer = new Outer(list); 
     OuterMost outermost = new OuterMost(outer); 

     Optional<String> innerValue = Optional.ofNullable(outermost) // outermost var can be null, hence using Optional.ofNullable 
       .map(OuterMost::getOuter) 
       .map(Outer::getNested) 
       .map(Collection::stream) 
       .filter(Objects::nonNull) //findFirst throws null pointer if selected element is null, hence filtering out null 
       .flatMap(Stream::findFirst) 
       .map(Nested::getInner) 
       .map(Inner::getFoo); 


     System.out.println(innerValue.orElse("No Value")); 
    } 
} 

//Classes OuterMost>Outer>Nested(List)>Inner 

class OuterMost { 
    public OuterMost(Outer out) { 
     outer = out; 
    } 

    Outer outer; 

    Outer getOuter() { 
     return outer; 
    } 
} 

class Outer { 
    public Outer(List<Nested> nest) { 
     nested = nest; 
    } 

    List<Nested> nested; 

    List<Nested> getNested() { 
     return nested; 
    } 
} 

class Nested { 

    public Nested(Inner in) { 
     inner = in; 
    } 

    Inner inner; 

    Inner getInner() { 
     return inner; 
    } 
} 

class Inner { 
    public Inner(String val) { 
     foo = val; 
    } 

    String foo; 

    String getFoo() { 
     return foo; 
    } 
} 
+0

你需要收集结果 –

回答

3

你打电话,而不是调用它的Stream<Nested>Optional<Stream<Nested>>过滤器()。

使用

Optional<String> innerValue = Optional.ofNullable(outermost) // outermost var can be null, hence using Optional.ofNullable 
      .map(OuterMost::getOuter) 
      .map(Outer::getNested) 
      .map(nestedList -> nestedList.stream().filter(Objects::nonNull)) 
      .flatMap(Stream::findFirst) 
      .map(Nested::getInner) 
      .map(Inner::getFoo);