Flattening a list of items in Java 8 Additional pipeline

I have a value id

that can be null

. Then I need to call some service using this id

to get the list of trades and get the first trade null

from the list.

I currently have this working code

Optional.ofNullable(id)
    .map(id -> service.findTrades(id))
    .flatMap(t -> t.stream().filter(Objects::nonNull).findFirst())
    .orElse(... default value...); 

      

Is it possible to implement a more elegant line with a call flatMap

? I don't want to put a lot of logic in one stage of the pipeline.

Originally I expected to implement the logic this way

Optional.ofNullable(id)
    .flatMap(id -> service.findTrades(id))
    .filter(Objects::nonNull)
    .findFirst()
    .orElse(... default value...); 

      

But it Optional.flatMap

does not allow the list to be flattened into many of its elements.

+3


source to share


2 answers


I don't know if it's elegant or not, but here's a way to convert the optional in a stream before the streaming pipeline starts:

Trade trade = Optional.ofNullable(id)
    .map(service::findTrades)
    .map(Collection::stream)
    .orElse(Stream.empty()) // or orElseGet(Stream::empty)
    .filter(Objects::nonNull)
    .findFirst()
    .orElse(... default value...); 

      




In Java 9 will have a method , so you will be able to directly convert the optional to a stream Optional

.stream()

Trade trade = Optional.ofNullable(id)
    .stream() // <-- Stream either empty or with the id
    .map(service::findTrades) // <-- Now we are at the stream pipeline
    .flatMap(Collection::stream) // We need to flatmap, so that we
    .filter(Objects::nonNull)    // stream the elements of the collection
    .findFirst()
    .orElse(... default value...); 

      

+6


source


There is a better way to do this with StreamEx

StreamEx.ofNullable(id)
    .flatMap(id -> service.findTrades(id))
    .filter(Objects::nonNull)
    .findFirst()
    .orElse(... default value...); 

      



I just saw, " As Stuart Marks says, Rule # 4: It is generally a bad idea to create optional purpose-specific chaining methods from it in order to get the value .. " in the comments under another question :

+3


source







All Articles