Java 8 java.util.Map#computeIfAbsent with java.util.Optional
<p>Suppose I have a cache implemented as <code>java.util.Map</code> which stores (arbitrary) values for keys. As the values are not mandatorily present, the cache returns an <code>java.util.Optional</code> and is able to be provided with a <code>java.util.function.Supplier</code> to calculate the value for a given non-existing key.</p>

<p>My first naive approach was</p>

<pre><code>public class Cache0 {

    private final Map&lt;String, String&gt; mapping = new HashMap&lt;&gt;();

    public Optional&lt;String&gt; get(String key, Supplier&lt;Optional&lt;String&gt;&gt; supplier) {
        final Optional&lt;String&gt; valueOptional;

        if (this.mapping.containsKey(key)) {
            final String value = this.mapping.get(key);

            valueOptional = Optional.of(value);
        } else {
            valueOptional = supplier.get();

            if (valueOptional.isPresent()) {
                this.mapping.put(key, valueOptional.get());
            }
        }

        return valueOptional;
    }
}
</code></pre>

<p>but I found this very inelegant and as I learned about <code>java.util.Map#computeIfAbsent</code> I changed the code to the following</p>

<pre><code>public class Cache1 {

    private final Map&lt;String, String&gt; mapping = new HashMap&lt;&gt;();

    public Optional&lt;String&gt; get(String key, Supplier&lt;Optional&lt;String&gt;&gt; supplier) {
        final String value = this.mapping.computeIfAbsent(key, absentKey -&gt; this.getValue(supplier));

        return Optional.ofNullable(value);
    }

    private String getValue(Supplier&lt;Optional&lt;String&gt;&gt; supplier) {
        return supplier.get()
                .orElse(null);
    }
}
</code></pre>

<p>but what now bothers me is the redundant use of <code>java.util.Optional#ofNullable</code> in combination with the <code>null</code> result of the <code>getValue</code> method which is needed to provide <code>java.util.Map#computeIfAbsent</code> with the "default" value not to be inserted into the map.</p>

<p>In an ideal situation, something like the following would be possible</p>

<pre><code>public class Cache2 {

    private final Map&lt;String, String&gt; mapping = new HashMap&lt;&gt;();

    public Optional&lt;String&gt; get(String key, Supplier&lt;Optional&lt;String&gt;&gt; supplier) {
        return this.mapping.computeIfAbsent(key, absentKey -&gt; supplier.get());
    }
}
</code></pre>

<p>where <code>java.util.Map#computeIfAbsent</code> would skip the insertion if the second parameter represents an empty <code>java.util.Optional</code> and returns an <code>java.util.Optional#empty</code> instead but unfortunately the use of <code>java.util.Optional#empty</code> as "default" insert value for <code>java.util.Map#computeIfAbsent</code> is not supported and the code does not compile.</p>

<p>A further possibility would be to store a mapping of <code>String</code> to <code>java.util.Optional</code> but then the <code>java.util.Map</code> would store the <code>java.util.Optional#empty</code> as value contradicting my use-case again to be forced to store invalid mappings and removing/replacing them by hand later.</p>

<pre><code>public class Cache3 {

    private final Map&lt;String, Optional&lt;String&gt;&gt; mapping = new HashMap&lt;&gt;();

    public Optional&lt;String&gt; get(String key, Supplier&lt;Optional&lt;String&gt;&gt; supplier) {
        return this.mapping.computeIfAbsent(key, absentKey -&gt; supplier.get());
    }
}
</code></pre>

<p>Is anyone aware of a better approach to handle this kind of use-case or do I have to fall back to my implementation of <code>Cache1</code>?</p>