Optional.orElseChain ?
Remi Forax
forax at univ-mlv.fr
Sat Apr 18 09:46:10 UTC 2015
On 04/18/2015 01:58 AM, Andreas Lundblad wrote:
> On Fri, Apr 17, 2015 at 03:01:29PM -0700, Steven Schlansker wrote:
>> On Apr 17, 2015, at 2:37 PM, Remi Forax <forax at univ-mlv.fr> wrote:
>>> As you can see the code is not bad but the code of chain() could be simplified
>>> if there was a way on Optional to call a Supplier of Optional if an Optional is empty.
>>> Currently, orElse() takes a value, orElseGet takes a lambda that will return a value
>>> and there is no method that takes a lambda and return an Optional
>>> (like flatMap but but with a supplier that will be called if the Optional is empty).
>>>
>>> If we add the method orElseChain(Supplier<? extends Optional<T>> supplier)
>>> perhaps with a better name ?, then the code of chain is better:
>>>
>>> public default TypeProvider chain(TypeProvider provider) {
>>> return name -> loadType(name).orElseChain(() -> provider.loadType(name));
>>> }
>>>
>>> Am i the only one to think that this method is missing ?
>> We actually ran into the exact same problem, and wrote the following helper method:
>>
>> public static <X> Optional<X> unlessOpt(@Nonnull Optional<X> first, Supplier<Optional<X>> second) {
>> return first.isPresent() ? first : second.get();
>> }
>>
>> I don't think it's precisely the same as your solution, but it definitely indicates a missing method.
> There are similar discussion here:
> http://stackoverflow.com/questions/24599996/get-value-from-one-optional-or-another
>
> and here:
> http://stackoverflow.com/questions/28818506/java-8-optional-orelse-optional
Thanks Andreas,
the second link provides a clever answer
(which as usually with StackOverflow is not the most voted answer :( ),
return name -> loadType(name).map(Optional::of).orElseGet(() ->
provider.loadType(name));
by mapping using Optional::of, it creates an Optional of Optional then
orElseGet can be used
to unwrap it to either an Optional or if the Optional inside the
Optional is empty by calling the supplier.
while this solution works, it creates an Optional of Optional just to
workaround the fact that
there is no method orElseChain/orElseOptional.
>
> -- Andreas
cheers,
Rémi
More information about the core-libs-dev
mailing list