Denis Stephanov
Denis Stephanov

Reputation: 5231

Work with null value in Stream

I have some function with lambda which is returning some object or null

public Function<SomeObject1, SomeObject2> lambdaFunc = obj1 -> {
    // here I do some logic, convert obj1 to obj2 and on the end return obj2 or null
};

I am using that function in my stream like that:

someObj0.setObjects2(entity.getObjects1().stream().map(lambdaFunc).collect(Collectors.toSet()));

Here when lambdaFunc return null I got exception, I think it is due collect function. Is some pretty solution to do that? I will be ok if that stream return also null when lambdaFunc return null, and don't continue.

EDIT 1: Ok I tried filter(Objects::nonNull) function but I find out problem is with entity.getObjects1() so I need prevent call stream function if it return null, any ideas?

Upvotes: 0

Views: 361

Answers (2)

Beri
Beri

Reputation: 11610

You can sinply add filtering for nonNull values:

someObj0.setObjects2(
 Optional.ofNullable(entity.getObjects1())
.orElse(Coollections.emptyList()) // return original Object or singleton empty from Collections 
.stream()
.map(lambdaFunc)
.filter(Objects::nonNull) // add checking here
.collect(Collectors.toSet()));

Here you have two choices:

  • First would be to wrap getObjects1() in a Optional

  • Second would be more clean - never return null, initialize your object with empty collection at start. Methods that return collections should never return null, but an emptyCollection from Collections util class. So that you would not have to worry about the nulls.

so

class SomeObj0 {
private List<SomeObject1> col =Collections.emptyList();

// getters/setters

}

I assume your collections is a list, but you can prevent it with a Optional:)

Upvotes: 2

jbx
jbx

Reputation: 22128

I think this is the case where you should use Optional instead of null. You don't have much details about what entity.getObjects1() is doing, but one thing is for sure, if you avoid returning null all along it will save you a NullPointerException further on.

You can try something like this which is clearer as to the intent you are doing:

Optional.ofNullable(entity.getObjects1())
        .map(objects -> objects.stream()           
                               .filter(Objects::nonNull)
                               .map(lambdaFunc)
                               .collect(Collectors.toSet()))
        .ifPresent(someObj0::setObjects2)

If you change entity.getObjects1() to return Optional you avoid the first call to ofNullable().

I would also encapsulate the objects.stream() part to another method that takes the collection and lambda function and returns another collection, to make the code a bit clearer.

Upvotes: 0

Related Questions