因此,我发现了使用Java的Map computeIfAbsent
(使用java8)方法的好奇心,希望我能告诉我为什么会这样,因为我不能真正遵循该问题背后的逻辑。
因此,我有一个带有键的Map(显然),并且值是一个列表,并且在尚未设置键的情况下,我使用computeIfAbsent创建新列表。现在,当我使用整数作为密钥时,可以使用以下代码:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
但是当我尝试使用String作为键时
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
我收到错误The method computeIfAbsent(String, Function<? super String,? extends List<Object>>) in the type Map<String,List<Object>> is not applicable for the arguments (String, ArrayList::new)
。只是缺少实现吗?使用String键,我必须使用类似的方法,然后该方法可以再次使用。
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>());
也许有人可以启发我。谢谢:)
答案 0 :(得分:15)
映射函数-Function<? super K, ? extends V> mappingFunction
-将键映射到值,因此,当键为Integer
时,ArrayList::new
有效,因为ArrayList
的构造函数需要一个int(初始容量)。另一方面,它没有采用String
的构造函数。
由于密钥可能不应该影响ArrayList
的初始容量,因此您不应该在此使用方法引用(在两种情况下)。使用lambda表达式。
更清晰地说:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
行为类似于:
List<Object> list = map.computeIfAbsent(1, k -> new ArrayList<>(k));
因此它将创建一个初始容量为1的ArrayList
。
另一方面:
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
行为类似于:
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
其中k
是String
,因此它不会通过编译。
答案 1 :(得分:9)
您的第二次尝试
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
实际上等于
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
,并且由于ArrayList
没有使用String作为参数的构造函数,因此它不起作用。第一个示例在创建包含一个元素的列表时起作用。