字典-Java map.get(key)-自动执行put(key)并在key不存在时返回?
我讨厌以下模式:
value = map.get(key);
if (value == null) {
value = new Object();
map.put(key, value);
}
当嵌套图表示多维结构时,此示例仅会刮擦要编写的额外代码的表面。
我确信某个地方可以避免这种情况,但是我在Google搜索中所做的努力没有任何意义。 有什么建议么?
7个解决方案
47 votes
的
java.util.concurrent.ConcurrentMap
和从Java 8
Java.util.Map
已
putIfAbsent(K key, V value)
它返回映射到键的值,或者插入给定的值;如果没有为键映射任何值,则返回null。
如果您需要懒惰的价值评估,
computeIfAbsent(K key, Function super K,? extends V> mappingFunction)
Roger Lindsjö answered 2020-01-19T14:14:50Z
33 votes
Java 8向Map添加了不错的方法:compute,computeIfPresent,computeIfAbsent
要实现您所需要的:
Object existingOrCreated = map.computeIfAbsent(key, (k) -> new Object());
iTake answered 2020-01-19T14:15:15Z
3 votes
这种模式的问题在于,您必须以某种方式定义在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提供无参数的构造函数。 或者,您可以简单地传递应使用的默认值。
Thomas answered 2020-01-19T14:15:49Z
3 votes
您可以使用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的撰稿人。
Nikhil Nanivadekar answered 2020-01-19T14:16:31Z
1 votes
编辑:请注意,长期以来不建议使用下面提到的功能,而应使用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);
Christian Semrau answered 2020-01-19T14:17:00Z
1 votes
无论如何,如果您不希望在地图中获取默认数据,
map.getOrDefault(key, defaultValue);
javadocs
letthefireflieslive answered 2020-01-19T14:17:24Z
0 votes
也许我没有看到整个问题,但是如何使用继承或组合将该行为添加到Map对象呢?
Trein answered 2020-01-19T14:17:45Z