Java Optional.ifPresentOrElse with return value

Viewed 20783

In Java, I have recently began to adopt the Optional type more in my code. This allows for better null-value handling and to some extend also safer code. Optional has the ifPresentOrElse method which allows you to perform a specific action for when a value is present, or a specific action for when no value is present. However, this method does not allow you to declare a return type.

Is there an easy way I can use optionals and a ifPresentOrElse-like method to return values while unwrapping an Optional?

2 Answers

Assuming following declarations (EDIT: note Consumer and Runnable are interfaces from @ImJustACowLol's self-answer, not java.util interfaces. For case the self-answer were deleted, the interfaces are same as those in java.util except the functional interface method has generic return type instead of void. Anyway the naming should have been chosen differently.):

Consumer<InputType, OutputType> yourConsumer = ...;
Runnable<OutputType> yourRunnable = ...;
Optional<InputType> yourOptional = ...;

you can compose following statement

OutputType result = yourOptional.map(yourConsumer).orElseGet(yourRunnable);

which admittedly doesn't fit in single method call, though still is concise and readable enough, IMHO.

Unfortunately, subclassing Optional is impossible as all of it's initializers are private. So any solution would have to come for a class or type that is not a subclass of Optional. The convenience method + interfaces below provides the desired behavior.

public interface Consumer<InputType, OutputType> {
    public OutputType consume(InputType inputType);
}

public interface Runnable<OutputType> {
    public OutputType run();
}

public static <ReturnType, OptionalType> ReturnType ifPresentOrElse(Optional<OptionalType> optional, Consumer<OptionalType, ReturnType> consumer, Runnable<ReturnType> runnable) {
    return optional.isPresent() ? consumer.consume(optional.get()) : runnable.run();
}
Related