I need a map that can hold null values and can return Optional wrapped value.
- I know
HashMapcan have null values, but it will not make it apparent to caller that value can be null. - The easiest alternative is to use
Map<K, Optional<V>>, but usingOptionalfor data type is not ideal. (Relevant SO post about usingOptionalonly for return: Use of Optional in a map) - I couldn't extend
HashMapclass very well with itsentrySet()method still facing the same null value issue, so I wrote my class that wrapsHashMapand hasget()and customEntry.getValue()that returnsOptionalwrapped value. (still figuring out how to write a version ofCollectors.toMapfor this class) - The problem now is the class is not easily "replaceable" with
Map(not programming to interface) and a custom-not-much-extensible-map is circulating in my business logic that I am slightly uncomfortable with.
public class CustomMap<K, V> {
private final Map<K, V> map;
public CustomMap() {
map = new HashMap<>();
}
public Optional<V> get(@NonNull final K k) { // Lombok.NonNull
return Optional.ofNullable(map.get(k));
}
public void put(@NonNull final K k, @Nullable final V v) {
map.put(k, v);
}
public Set<Entry<K, V>> entrySet() {
return map.entrySet().stream()
.map(e -> new Entry(e.getKey(), e.getValue()))
.collect(toImmutableSet());
}
public Set<K> keySet() {
return map.keySet();
}
public static class Entry<K, V> {
private final K k;
private final V v;
public Entry(K k, V v) {
this.k = k;
this.v = v;
}
public K getKey() {
return k;
}
public Optional<V> getValue() {
return Optional.ofNullable(v);
}
}
}
Expectation: customMap.get(K) should return Optional wrapped object and customMap.put(K, V) should not need to take Optional<V> as input. CustomMap should be able to act as Map.
There should be cleaner and extensible way to achieve this and I feel I am missing something obvious. Any suggestions?