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
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 .
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."
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.
We can check whether the returned Optional value is empty or non-empty using the isPresent() method.
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*/
)
);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With