如何使用泛型创建激活键?此代码甚至无法编译:
/* populate the map with a new value if the key is not in the map */
private <K,V> boolean autoVivify(Map<K,V> map, K key)
{
if (! map.containsKey(key))
{
map.put(key, new V());
return false;
}
return true;
}
如何使用泛型创建激活键?此代码甚至无法编译:
/* populate the map with a new value if the key is not in the map */
private <K,V> boolean autoVivify(Map<K,V> map, K key)
{
if (! map.containsKey(key))
{
map.put(key, new V());
return false;
}
return true;
}
在 Java-8 中,提供 aSupplier
和使用是合理的computeIfAbsent
:
private <K,V> boolean autoVivify(Map<K,V> map, K key, Supplier<V> supplier) {
boolean[] result = {true};
map.computeIfAbsent(key, k -> {
result[0] = false;
return supplier.get();
});
return result[0];
}
使用示例:
Map<String, List<String>> map = new HashMap<>();
autoVivify(map, "str", ArrayList::new);
请注意,与containsKey/put
解决方案不同,使用computeIfAbsent
并发映射是安全的:不会发生竞争条件。
您需要告诉方法如何创建值。
interface Producer<T> {
T make();
}
private <K, V> boolean autoVivify(Map<K, V> map, K key, Producer<V> maker) {
if (!map.containsKey(key)) {
map.put(key, maker.make());
return false;
}
return true;
}
或者 - 使用null
。HashMap
可以包含null
虽然TreeMap
可能有困难。
private <K, V> boolean autoVivify(Map<K, V> map, K key) {
if (!map.containsKey(key)) {
map.put(key, null);
return false;
}
return true;
}
如果V
有一个没有参数的构造函数,你可以使用反射来创建一个实例
private <K, V> boolean autoVivify(Map<K, V> map, K key, Class<V> clazz) throws Exception {
if (!map.containsKey(key)) {
map.put(key, clazz.getConstructor().newInstance());
return false;
}
return true;
}
Map<Integer, String> map = new HashMap<>();
autoVivify(map, 3, String.class);