Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java streams: Optional to stream

This is my code:

Optional<Application> application = this.applicationDao.findById(id);

where, Application class is:

public class Application {
    private String code;    
    private Collection<ApplicationQuote> quotes;
}

I need to create an stream from return Optional<Application> like this:

(app, quote-1) > (app, quote-2) > ... > (app, quote-n)

Where each quote-n is inside returned Optional<Application>.quotes.

I hope I've explained so well.

Up to now, I've been able to write this code, but I don't feel confortable with that:

Optional<Application> application = this.applicationDao.findById(id);
    application.map(app -> Pair.of(app, Optional.ofNullable(app.getQuotes())))
        .filter(quote -> quote.getValue().isPresent())
        .map(quote -> quote.getValue().get().stream().map(q -> Pair.of(quote.getKey(), q)));
like image 453
Jordi Avatar asked Oct 11 '25 13:10

Jordi


2 Answers

You're overcomplication things here. i.e you don't actually need to wrap app.quotes into an optional only to check if it's non-null (which actually abuses the main purpose of Optional) etc...

since you want a Stream<Pair<Application, ApplicationQuote>> you can do so as follows:

JDK8:

application.filter(app -> app.getQuotes() != null)
           .map(Stream::of).orElseGet(Stream::empty)
           .flatMap(app -> app.getQuotes().stream().map(quote -> Pair.of(app, quote)));

JDK9:

application.filter(app -> app.getQuotes() != null).stream()
           .flatMap(app -> app.getQuotes().stream().map(quote -> Pair.of(app, quote)));
like image 63
Ousmane D. Avatar answered Oct 14 '25 04:10

Ousmane D.


Optional.orElse

Ideally what you currently have is Optional<Stream<Pair<Application, ApplicationQuote>>> optionalPairStream and what you might just be looking for just add a default case and get just the Stream as :

Stream<Pair<Application, ApplicationQuote>> pairStream = application
        .map(app -> Pair.of(app, Optional.ofNullable(app.getQuotes())))
        .filter(quote -> quote.getValue().isPresent())
        .map(quote -> quote.getValue().get().stream().map(q -> Pair.of(quote.getKey(), q)))
        .orElse(Stream.empty());

Optional.stream

With Java9, you can update the same code as:

Stream<Pair<Application, ApplicationQuote>> pairStream = application
           .map(app -> Pair.of(app, Optional.ofNullable(app.getQuotes())))
           .filter(quote -> quote.getValue().isPresent())
           .stream() // new API
           .flatMap(quote -> quote.getValue().orElse(Collections.emptyList())
                   .stream().map(q -> Pair.of(quote.getKey(), q)));
like image 39
Naman Avatar answered Oct 14 '25 03:10

Naman