How to use Java 8 Optionals, performing an action if all three are present?

hughjdavey picture hughjdavey · Jan 25, 2018 · Viewed 18.2k times · Source

I have some (simplified) code that uses Java Optionals:

Optional<User> maybeTarget = userRepository.findById(id1);
Optional<String> maybeSourceName = userRepository.findById(id2).map(User::getName);
Optional<String> maybeEventName = eventRepository.findById(id3).map(Event::getName);

maybeTarget.ifPresent(target -> {
    maybeSourceName.ifPresent(sourceName -> {
        maybeEventName.ifPresent(eventName -> {
            sendInvite(target.getEmail(), String.format("Hi %s, $s has invited you to $s", target.getName(), sourceName, meetingName));
        }
    }
}

Needless to say, this looks and feels bad. But I can't think of another way to do this in a less-nested and more readable way. I considered streaming the 3 Optionals, but discarded the idea as doing a .filter(Optional::isPresent) then a .map(Optional::get) feels even worse.

So is there a better, more 'Java 8' or 'Optional-literate' way of dealing with this situation (essentially multiple Optionals all needed to compute a final operation)?

Answer

Sharon Ben Asher picture Sharon Ben Asher · Jan 25, 2018

I think to stream the three Optionals is an overkill, why not the simple

if (maybeTarget.isPresent() && maybeSourceName.isPresent() && maybeEventName.isPresent()) {
  ...
}

In my eyes, this states the conditional logic more clearly compared to the use of the stream API.