ha9u63a7
ha9u63a7

Reputation: 6862

How to convert an Optional of one type of list to another

I have an optional Optional<TypeA> from which I can do a map function and get Optional<List<TypeB>>.

But I would like to now map it to Optional<List<TypeC>> and then orElse() it. So putting in pseudo code

Optional.ofNullable(fooReturnsTypeA()).map(TypeA::barReturnsListTypeB()).{?}.orElse(new ArrayList<TypeC>());

I know how to use map function, but it's been a while dealing with Optional with map. So, I might be just staring at the answer. Could someone help me with {?} part?

Upvotes: 1

Views: 1238

Answers (3)

Oboe
Oboe

Reputation: 2723

First, I would replace the orElse with orElseGet. Depending on your code, using orElseGet instead of orElse can improve your performance. The parameter of orElse is evaluated even when the Optional is non-empty. On the other hand, the parameter of orElseGet is evaluated only when the Optional is empty. In your specific case, you may be instantiating unnecessary ArrayLists. From the Javadoc:

Supplier method passed as an argument is only executed when an Optional value is not present.

You can also dismiss the {?} by using a stream in the map.

Optional.ofNullable(fooReturnsTypeA())
    .map(typeA -> typeA.barReturnsListTypeB().stream()
            .map(TypeB::barReturnsTypeC).collect(Collectors.toList()))
    .orElseGet(() -> new ArrayList<TypeC>());

Note: see this for more information about the difference between orElse and orElseGet.

Upvotes: 0

wojdzie
wojdzie

Reputation: 61

You can use another map and write method to convert List<TypeB> to List<TypeC>.

You're code will look like this:

    Optional.ofNullable(fooReturnsTypeA())
    .map(TypeA::barReturnsListTypeB())
    .map(this::convert)
    .orElse(new ArrayList<TypeC>());

And your method to convert:

    private List<TypeC> convert(List<TypeB> list) {
    // conversion logic
    // return List<TypeC>
}

Upvotes: 0

dan1st
dan1st

Reputation: 16476

What about this?

Optional.ofNullable(fooReturnsTypeA())
    .map(TypeA::barReturnsListTypeB())
    .map(typeBList->typeBList
        .stream()
        .map(TypeB::barReturnsTypeC)
        .collect(Collectors.toList())
    )
    .orElse(new ArrayList<TypeC>())

This basically creates a new Stream in .map and uses it to convert all elements of TypeB to TypeC (assuming TypeB has a method barReturnsTypeC without parameters that returns an instance of TypeC).

Upvotes: 1

Related Questions