1

如何使用泛型创建激活键?此代码甚至无法编译:

/* 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;
}
4

3 回答 3

5

在 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并发映射是安全的:不会发生竞争条件。

于 2015-08-26T10:11:57.447 回答
1

您需要告诉方法如何创建值。

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;
}

或者 - 使用nullHashMap可以包含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;
}
于 2015-08-26T10:03:34.917 回答
1

如果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);
于 2015-08-26T10:03:41.550 回答