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