Если я вас правильно понимаю, вы хотите сделать использование Optionals очевидным и неохотно внедрять какую-либо реализацию пользовательской карты, которая отличается от реализации Map;это противоречит вашему утверждению о том, что необязательный тип данных не идеален.
Предполагая, что вы просто не хотите хранить необязательные экземпляры на карте, возможным решением будет реализация Map, заключающая в себе (внутренний) Map<K,V>
с нулевыми значениями, такими как Map<K, Optional<V>>
, например
import java.util.AbstractMap;
import java.util.Collection;
import java.util.Collections;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
public class OptionalMap<K, V> implements Map<K, Optional<V>> {
private final Map<K, V> map;
public OptionalMap(Map<K, V> map) {
this.map = map;
}
@Override
public void clear() {
map.clear();
}
@Override
public boolean containsKey(Object key) {
return map.containsKey(key);
}
@Override
public boolean containsValue(Object value) {
if (!(value instanceof Optional)) {
return false;
}
return map.containsValue(((Optional<?>)value).get());
}
@Override
public Set<Entry<K, Optional<V>>> entrySet() {
return
map.entrySet().stream()
.map(e -> new AbstractMap.SimpleEntry<K, Optional<V>>(e.getKey(), Optional.ofNullable(e.getValue())))
.collect(Collectors.collectingAndThen(Collectors.toSet(), Collections::unmodifiableSet));
}
@Override
public Optional<V> get(Object key) {
return Optional.ofNullable(map.get(key));
}
@Override
public boolean isEmpty() {
return map.isEmpty();
}
@Override
public Set<K> keySet() {
return map.keySet();
}
@Override
public Optional<V> put(K key, Optional<V> value) {
final Optional<V> previous = Optional.ofNullable(map.get(key));
map.put(key, value.orElse(null));
return previous;
}
@Override
public void putAll(Map<? extends K, ? extends Optional<V>> other) {
Map<K, V> unwrappedMap =
other.entrySet().stream()
.<Entry<K, V>>map(entry -> new AbstractMap.SimpleEntry<K, V>(entry.getKey(), entry.getValue().orElse(null)))
.collect(Collectors.toMap(Entry::getKey, Entry::getValue));
map.putAll(unwrappedMap);
}
@Override
public Optional<V> remove(Object key) {
return Optional.ofNullable(map.remove(key));
}
@Override
public int size() {
return map.size();
}
@Override
public Collection<Optional<V>> values() {
return
map.values().stream()
.map(e -> Optional.ofNullable(e))
.collect(Collectors.collectingAndThen(Collectors.toList(), Collections::unmodifiableList));
}
}