Java 8 stream findFirst抛出NPE,无法从流中筛选出非空对象

Java 8 stream findFirst抛出NPE,无法从流中筛选出非空对象,java,java-8,java-stream,Java,Java 8,Java Stream,我试图访问内部对象而不会导致空指针异常。 我希望避免手动编写if条件null检查,而是使用java8特性 我从findFirst方法中获得Nullpointer异常。我知道如果所选元素为null,findFirst会返回null指针异常,所以在调用findFirst之前,我尝试使用filter(objects::nonNull)过滤掉null对象,但它仍然抛出null指针 看起来我的过滤不起作用,但我不知道为什么 Please find below the code package main.

我试图访问内部对象而不会导致空指针异常。 我希望避免手动编写if条件null检查,而是使用java8特性

我从findFirst方法中获得Nullpointer异常。我知道如果所选元素为null,findFirst会返回null指针异常,所以在调用findFirst之前,我尝试使用filter(objects::nonNull)过滤掉null对象,但它仍然抛出null指针

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

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;
    }
}
请在下面找到代码
包main.java;
导入java.util.*;
导入java.util.stream.stream;
公共类选项测试{
公共静态void main(字符串参数[]){
内部内部=新内部(“有价值”);
嵌套嵌套=新嵌套(在中);
列表=新的ArrayList();
//list.add(nest);//注释掉以测试失败场景
list.add(null);//添加了null
list.add(null);//添加了null
外部=新外部(列表);
最外层=新的最外层(外层);
Optional innerValue=Optional.ofNullable(最外层)//最外层的变量可以为null,因此使用Optional.ofNullable
.map(最外层::getOuter)
.map(外部::getNested)
.map(集合::流)
.filter(Objects::nonNull)//findFirst在所选元素为null时抛出null指针,从而过滤掉null
.flatMap(流::findFirst)
.map(嵌套::getInner)
.map(内部::getFoo);
System.out.println(innerValue.orElse(“无值”);
}
}
//类最外层>外层>嵌套(列表)>内部
类最外层{
公共最外层(外部){
外部=外部;
}
外部的;
外部getOuter(){
返回外部;
}
}
类外部{
公共外部(列表嵌套){
嵌套=嵌套;
}
列表嵌套;
列表getNested(){
返回嵌套;
}
}
类嵌套{
公共嵌套(内部插入){
内=in;
}
内在的;
内部getInner(){
返回内部;
}
}
班级内部{
公共内部(字符串val){
foo=val;
}
串福;
字符串getFoo(){
返回foo;
}
}
您在
可选
上调用filter(),而不是在
流上调用它

使用

Optional innerValue=Optional.ofNullable(最外层)//最外层的var可以为null,因此使用Optional.ofNullable
.map(最外层::getOuter)
.map(外部::getNested)
.map(nestedList->nestedList.stream().filter(Objects::nonNull))
.flatMap(流::findFirst)
.map(嵌套::getInner)
.map(内部::getFoo);

您需要收集结果
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);