RFR 8080418 Add Optional.or()

Paul Sandoz paul.sandoz at oracle.com
Fri Sep 25 12:30:46 UTC 2015

On 25 Sep 2015, at 14:00, Tagir F. Valeev <amaembo at gmail.com> wrote:

> Hello!
> Quite interesting and long awaited features (at least according to
> StackOverflow questions).

All of them? or just the first?

> Isn't it a good idea to provide also a way
> to transfer between Optional types like "mapToInt", "mapToObj", etc.,
> like it's done in Stream API?

I don’t wanna go there, my response is transform Optional* into a *Stream. An argument for adding mapOrElseGet (notice that the primitive variants return U) is that other functionality can be composed from it.

> PS> 2) add to all variants a mapOrElseGet (otherwise known as a
> PS> “fold”), which is the equivalent of
> PS> map(mapper).orElseGet(supplier). That is arguably less
> PS> mind-bending to use when transforming from Optional<T> to Optional<U>.
> The proposed implementation is the following:
>    public<U> U mapOrElseGet(Function<? super T, ? extends U> mapper,
>                             Supplier<? extends U> supplier) {
>        if (!isPresent()) {
>            return supplier.get();
>        } else {
>            return mapper.apply(value);
>        }
>    }
> It documents that:
>     * @throws NullPointerException if the mapping function or the supplying
>     *         function is {@code null}

Thanks, yes, i need to update that to be consistent with the existing functional accepting termination methods.

> However in fact it throws not always. For example, this call will not
> throw:
>  Optional.empty().mapOrElseGet(null, () -> "x");
> To me it seems that this should be fixed (possibly adding
> requireNonNull checks) as it could become the source of silent bugs.
> Also you say that it's equivalent to the map().orElseGet() chain.
> However this one throws:
>  Optional.empty().<String>map(null).orElseGet(() -> "x");
> There's also another problem. The orElseGet(null) is documented to
> work to work fine for non-empty optional

> (why on the Earth it was specified this way?).

Arguably it was a mistake that we did not catch in the frenzy of Java 8 feature freeze. I would like to revert it but existing code might already be reliant on it :-(


> So there's good question whether the "supplier"
> argument of "mapOrElseGet" should be allowed to be null for non-empty
> optional (to conform with "orElseGet") or should not be allowed (to
> conform with "mapper" argument).
> With best regards,
> Tagir Valeev.

More information about the core-libs-dev mailing list