简体   繁体   中英

Java 8 stream findFirst throwing NPE, Unable to filter out nonNull objects from stream

I was trying to access inner objects without causing null pointer exceptions. I wanted to avoid manually written if condition null checks and use utilize java 8 features instead.

I am getting Nullpointer exceptions from findFirst method. I was aware that findFirst returns null pointer exception if selected element is null, So i tried filtering out null objects using filter(Objects::nonNull) before calling findFirst, but it was still throwing null pointer.

Looks like my filtering is not working, but i don't know why.

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;
    }
}

You're calling filter() on the Optional<Stream<Nested>> , instead of calling it on the Stream<Nested> .

Use

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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM