【发布时间】:2019-05-22 07:11:13
【问题描述】:
我需要一个可以保存空值并且可以返回可选包装值的映射。
- 我知道
HashMap可以有空值,但它不会让调用者明白该值可以为空。 - 最简单的替代方法是使用
Map<K, Optional<V>>,但使用Optional作为数据类型并不理想。 (有关使用Optional仅用于返回的相关 SO 帖子:Use of Optional in a map) - 我无法很好地扩展
HashMap类,因为它的entrySet()方法仍然面临同样的空值问题,所以我编写了包装HashMap并具有get()和返回的自定义Entry.getValue()的类Optional包装值。 (仍在研究如何为此类编写Collectors.toMap的版本) - 现在的问题是这个类不容易被
Map“替换”(不是对接口进行编程),而且我的业务逻辑中有一个自定义的不可扩展映射,这让我有点不舒服。
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);
}
}
}
期望:customMap.get(K) 应该返回 Optional 包装对象,customMap.put(K, V) 不需要将 Optional<V> 作为输入。 CustomMap 应该可以充当Map。
应该有更清洁和可扩展的方式来实现这一点,我觉得我错过了一些明显的东西。有什么建议吗?
【问题讨论】:
-
您可以在某些 MapUtils 类中将该行为定义为静态方法: public static
Optional optionalGet(Map elements, K key) { return Optional. ofNullable(elements.get(key)); } -
它不会成为
Map<K,V>的直接替代品,因为该接口表示您必须从get返回V,而不是Optional<V>。因此,所有get调用者都可以使用的静态辅助方法是最好的方法。