Adding Optionals/null safety to a nested flatMap/stream

52 Views Asked by At

I'm having trouble making my method null-safe using streams and flatMap..

My input is a List<RequestSlot>

And the objects are nested as such:

        Request
                OuterItem
                        List<InnerItem>

This is working to flatten the lists and create one List, but I'm unsure how to add Optionals here to make this null safe for each map/stream step.

  final List<InnerItem> innerItem = request.stream()
          .map(RequestSlot::getOuterItem)
          .flatMap(outerItem -> outerItem.getInnerItem().stream()).collect(Collectors.toList());

I have tried using Stream.ofNullable but that ends up creating a stream that I'm unsure how to then collect. Any pointers?

1

There are 1 best solutions below

1
Sweeper On BEST ANSWER

You don't actually need to use Optional. Just filter(Objects:nonNull) everywhere after mapping to something that might be null. This filters out all the null things

// assuming request itself is not null
final List<InnerItem> innerItem = request.stream()
    .filter(Objects:nonNull) // list elements might be null
    .map(RequestSlot::getOuterItem) 
    .filter(Objects:nonNull) // outer item might be null
    .map(OuterItem::getInnerItem)
    .filter(Objects:nonNull) // inner items list might be null
    .flatMap(Collection::stream) // innerItemList -> innerItemList.stream()
    .filter(Objects:nonNull) // inner item list might contain nulls
    .toList();

If you really want to use Stream.ofNullable, use the pattern flatMap(x -> Stream.ofNullable(x.getX())) (where getX might return null).

final List<InnerItem> innerItem = request.stream()
    .filter(Objects:nonNull) // list elements might be null
    .flatMap(requestSlot -> Stream.ofNullable(requestSlot.getOuterItem())) // outer item might be null
    .flatMap(outerItem -> Stream.ofNullable(outerItem.getInnerItem())) // inner item list might be null
    .flatMap(Collection::stream) // innerItemList -> innerItemList.stream()
    .filter(Objects:nonNull) // inner item list might contain nulls
    .toList();