字典-Java map.get(key)-自动执行put(key)并在key不存在时返回?

我讨厌以下模式:

value = map.get(key);
if (value == null) {
value = new Object();
map.put(key, value);
}

当嵌套图表示多维结构时,此示例仅会刮擦要编写的额外代码的表面。

我确信某个地方可以避免这种情况,但是我在Google搜索中所做的努力没有任何意义。 有什么建议么?


java.util.concurrent.ConcurrentMap

和从Java 8

Java.util.Map

putIfAbsent(K key, V value)

它返回映射到键的值,或者插入给定的值;如果没有为键映射任何值,则返回null。

如果您需要懒惰的价值评估,

computeIfAbsent(K key, Function super K,? extends V> mappingFunction)


Java 8向Map添加了不错的方法:compute,computeIfPresent,computeIfAbsent

要实现您所需要的:

Object existingOrCreated = map.computeIfAbsent(key, (k) -> new Object());


这种模式的问题在于,您必须以某种方式定义在valueClass返回null的情况下应使用的值。

当然,那里有图书馆,而IIRC也有一些较新的馆藏可以做到这一点,但是不幸的是,我不记得是哪个图书馆。

但是,如果您具有创建新值的标准方法,则可以自己编写实用程序方法。 这样的事情可能会起作用:

public static V safeGet(K key, Map map, Class valueClass) throws /*add exceptions*/ {
V value = map.get(key);
if( value == null ) {
value = valueClass.newInstance();
map.put( key, value );
}
return value;
}

请注意,您要么必须抛出反射异常,要么在方法中处理它们。 此外,这需要valueClass提供无参数的构造函数。 或者,您可以简单地传递应使用的默认值。


您可以使用Eclipse Collections中的MutableMap和Object,它们返回映射到键的值,或者插入给定值,如果没有值映射到键,则返回给定值。

您可以使用方法参考来创建新的Object:

MutableMap map = Maps.mutable.empty();

Object value = map.getIfAbsentPut("key", Object::new);

或者,您可以直接创建一个新的Object:

MutableMap map = Maps.mutable.empty();

Object value = map.getIfAbsentPut("key", new Object());

在第一个示例中,仅当没有值映射到键时才创建对象。

在第二个示例中,无论如何都将创建对象。

注意:我是Eclipse Collections的撰稿人。


编辑:请注意,长期以来不建议使用下面提到的功能,而应使用CacheBuilder。

Guava库具有一个“计算地图”,请参见MapMaker.makeComputingMap(Function)。

Map map = new MapMaker().makeComputingMap(
new Function() {
public String apply(Stringt) {
return new Object();
}
});

如果您多次需要该Function,请将其提取到一个实用工具类中,然后像这样创建Map(其中MyFunctions.NEW_OBJECT是静态Function实例):

Map map = new MapMaker()

.makeComputingMap(MyFunctions.NEW_OBJECT);


无论如何,如果您不希望在地图中获取默认数据,

map.getOrDefault(key, defaultValue);

javadocs


也许我没有看到整个问题,但是如何使用继承或组合将该行为添加到Map对象呢?