A suggestion: Map.checkAndGet
David Holmes
david.holmes at oracle.com
Wed Oct 31 18:11:06 PDT 2012
On 1/11/2012 1:44 AM, Zhong Yu wrote:
> How can we add any default method to an interface, since its behavior
> might conflict with some unknown subclass' unknown additional
> contracts?
This is a risk that has to be taken to allow the platform to evolve. We
can mitigate it by considering the "obvious" kinds of specialization but
we can not avoid them.
Thread-safety is a very obvious candidate here and there are
implications for both concurrent data structures (like
ConcurrentHashMap) and simpler thread-safe structures, like the
synchronized collection wrappers. For issues within the JDK libraries we
have to solve any problems that arise. For issues external to the JDK
this just has to be part of the JDK8 migration process.
In some cases it may be necessary to re-abstract new methods so that the
default implementation is not used. For example if someone has a
ConcurrentList interface for which new default implementations in List
would not be thread-safe, then ConcurrentList should be updated to
re-abstract those methods (ie re-define them with no default
implementation). Of course inside the JDK we would have to ensure there
are correct, concrete implementations for all of the concrete types.
David
-----
>
> On Tue, Oct 30, 2012 at 11:49 AM, Mike Duigou<mike.duigou at oracle.com> wrote:
>> Unfortunately such a method would introduce non-atomic behaviour for synchronized maps so we can't add it.
>>
>> Mike
>>
>> On Oct 30 2012, at 08:25 , Boaz Nahum wrote:
>>
>>> The pattern
>>> map.containsKey(k) ? map.get() : othervAlue
>>> (walks on tree twice)
>>>
>>> repeats itself so many times, as in Mappers:
>>>
>>> public static<T, U> Mapper<T, U> forMap(Map<? super T, ? extends U> map,
>>> U defaultValue) {
>>> Objects.requireNonNull(map);
>>>
>>> return t -> map.containsKey(t) ? map.get(t) : defaultValue;
>>> }
>>>
>>>
>>> Now that we have 'default methods', we can add to Map:
>>>
>>> NullableOptional<V> checkAndget(K key) default {
>>>
>>> if (containsKey(key)) {
>>> return new NullableOptional<>(get(key));
>>> } else {
>>> return NullableOptional.empty();
>>> }
>>> }
>>>
>>> **and** implement it in Map implementation in such way that will walk on
>>> tree only once.
>>> (Assume creating instance of NullableOptional is more efficient )
>>>
>>> forMap becomes:
>>>
>>> public static<T, U> Mapper<T, U> forMap(MyMap<? super T, ? extends U> map,
>>> U defaultValue) {
>>> Objects.requireNonNull(map);
>>>
>>>
>>> return t -> {
>>> NullableOptional<? extends U> o = map.checkAndget(t);
>>> return o.isPresent() ? o.get() : defaultValue;
>>> //return o.orElse(defaultValue);
>>> };
>>> }
>>>
>>
>>
>
More information about the lambda-dev
mailing list