Search code examples
javajava-streamoption-typenull-check

Using Java Optional within stream mapping


I have code like this:

public void processList(List<String> list) {

    for (String item : list) {
        Object obj = getObjectForString(item);
        if (obj != null) {
            doSomethingWithObject(obj);
        } else {
            System.err.println("Object was null for " + item);
        }
    }
}

Ideally I would like to streamline this and avoid the null check using list.stream().map( *blah, blah, blah* ), and doSomethingWithObject if the object is not null, but log the error otherwise (by using the orElse method on an optional). I'm not super savvy with this Java 8 functionality and not sure if there is a nice, slick way to do what I want here or not. Suggestions?

Edit to add a failed attempt at this:

list.stream()
    .map(p -> getObjectForString(p))
    .map(Optional::ofNullable)
    .forEach(
        p -> p.ifPresentOrElse(
            r -> doSomethingWithObject(r),
            () -> System.err.println("Object was null")
        ));

Even if that code behaved the way I want, it still doesn't append the String from the original list to the error message as I would like it to. But maybe that's too much complexity to try to accomplish with streams like this.


Solution

  • we should propagate the item even after conversion. The slick way is using tuple or pair.

    I used Tuple from vavr functional library to do the same. And below is the code for your reference

    list.stream()
                    .map(p -> Tuple.of(p, getObjectForString(p)).map2(Optional::ofNullable))
                    .forEach(p -> p._2.ifPresentOrElse(
                                r -> doSomethingWithObject(r),
                                () -> System.err.println("Object was null" + p._1))
                    );