Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write "if optional is empty, call next method returning optional, if not return this non-empty optional" several times in a functional style? [duplicate]

Assume I have this method

public Optional<String> validateAndReturnErrorMessage(SomeEcommerceSale s) {
    Optional<String> errorWithItem = validateItem(s.getItem());
    if (errorWithItem.isPresent()) return errorWithItem;

    Optional<String> errorWithPayment = validatePayment(s.getPayment());
    if (errorWithPayment.isPresent()) return errorWithPayment;
    
    // assume I have several other cases like the 2 above

    return Optional.empty(); // meaning there were no errors

My problem is, since OrElse and OrElseGet return <T> and not Optional<T>, is there a native way to do rewrite this into a more functional way without having several loosely coupled return statements?

EDIT

I would like to check validations one by one, since they are external and heavy. This way, I would call only the necessary ones

like image 965
rado Avatar asked May 05 '21 11:05

rado


People also ask

What does Optional return if empty?

Method Summary Returns an empty Optional instance. Indicates whether some other object is "equal to" this Optional. If a value is present, and the value matches the given predicate, return an Optional describing the value, otherwise return an empty Optional .

How do I return Optional instead of null?

In Java 8 you can return an Optional instead of a null . Java 8 documentation says that an Optional is "A container object which may or may not contain a non-null value. If a value is present, isPresent() will return true and get() will return the value."

Which method will return a default value when Optional instance is empty?

The orElseGet() method takes a Supplier that returns a value when the Optional is empty. Otherwise, it returns the encapsulated value. The orElseThrow() method takes a Supplier that returns an exception when the Optional is empty.

How do you know if an Optional value is empty?

We can check whether the returned Optional value is empty or non-empty using the isPresent() method.


Video Answer


1 Answers

This kind of situation is what Optional.or was added for. It was added in Java 9, so if you're still on Java 8 then you can't use it.

return validateItem(s.getItem())
    .or(() -> validatePayment(req.getPayment()))
    .or(() -> /*another one*/);

If you are stuck on Java 8, you could write a helper method

public static <T> Optional<T> firstNonEmpty(List<Supplier<Optional<T>>> supplierList) {
    for (Supplier<Optional<T>> supplier : supplierList) {
        Optional<T> value = supplier.get();
        if (value.isPresent()) return value;
    }
    return Optional.empty();
}

And it use it like so:

return firstNonEmpty(
    Arrays.asList(
        () -> validateItem(s.getItem()),
        () -> validatePayment(req.getPayment()),
        () -> /*another one*/
    )
);
like image 132
Michael Avatar answered Oct 04 '22 02:10

Michael