This is an offshoot of my other question: How to chain Optional#ifPresent() in lambda without nesting?
However, the problem now is how to provide a lambda solution where all of the optional values are available at the innermost scope:
B b = procA().flatMap(this::procB).orElseThrow(SomeException::new);
// Value from procA() is not available.
My original code was:
void SomeMethod() {
procA().ifPresent(a -> {
procB(a).ifPresent(b -> {
// Do something with a and b
return;
});
});
throw new SomeException();
}
I understand that the return
at the innermost scope is wrong. The new flatMap
example illustrates the correct behavior.
I am using ifPresent()
instead of get()
to avoid potential runtime exceptions where I might fail to check whether the value of an optional isPresent()
.
I find this question very interesting as chained calls with potential
null
returns are a common nuisance, and Optional can shorten the usual null check chain a lot. But the issue there is that the nature of the functional stream methods hides the intermediate values in the mapping functions. Nesting is a way to keep them available, but can also get annoying if the length of the call chain grows, as you have realized.I cannot think of an easy and lightweight solution, but if the nature of your project leads to these situations regularly, this util class could help:
You use it by wrapping an Optional or a plain value. When you then use the
map
method to chain method calls, it will provide a new ChainedOptional while storing the current value in a list. At the end (ifPresent
,orElseThrow
), you will not only get the last value, but also the list of all intermediate values. Since it is not known how many calls will be chained, I did not find a way to store those values in a type-safe way, though.See examples here:
Hope this helps. Let me know if you come up with a nicer solution.