Java Map computeIfAbsent问题

Fus*_*sel 13 java functional-programming java-8

所以我发现了Java的Map computeIfAbsent(使用java8)方法的好奇心,我希望有人能告诉我为什么会发生这种情况,因为我无法真正遵循该问题背后的逻辑.

所以,我有一个带有键的Map(显然),值是一个列表,当没有设置键时,我使用computeIfAbsent创建一个新列表.现在,当我使用Integer作为键时,我可以使用以下内容:

List<Object> list = map.computeIfAbsent(1, ArrayList::new);
Run Code Online (Sandbox Code Playgroud)

但是当我使用String作为密钥尝试使用时

List<Object> list = map.computeIfAbsent("key", ArrayList::new);
Run Code Online (Sandbox Code Playgroud)

我得到了错误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<>());
Run Code Online (Sandbox Code Playgroud)

也许有人可以启发我.谢谢 :)

Era*_*ran 16

映射函数- Function<? super K, ? extends V> mappingFunction-映射一键的值,所以当关键是Integer,ArrayList::new工作,由于ArrayList有一个构造采用int(初期容量).另一方面,它没有一个构造函数String.

由于密钥可能不应影响其初始容量,因此ArrayList不应在此处使用方法引用(在这两种情况下).使用lambda表达式.

为了更清楚:

List<Object> list = map.computeIfAbsent(1, ArrayList::new);
Run Code Online (Sandbox Code Playgroud)

表现类似于:

List<Object> list = map.computeIfAbsent(1, k -> new ArrayList<>(k));
Run Code Online (Sandbox Code Playgroud)

所以它将创建一个ArrayList初始容量为1.

另一方面:

List<Object> list = map.computeIfAbsent("key", ArrayList::new);
Run Code Online (Sandbox Code Playgroud)

表现类似于:

List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
Run Code Online (Sandbox Code Playgroud)

哪里k是a String,所以它不通过编译.

  • 更具体地说,`1-&gt; ArrayList :: new`实际上不会产生插入了值'1'的列表。 (2认同)
  • @Fussel如果用10亿替换`1`,可能会出现内存错误,因为Java会尝试分配一个能够存储10亿个元素的数组.请注意容量!=实际元素.空的`ArrayList`可以消耗任意数量的内存,具体取决于容量. (2认同)

Jan*_*sen 9

你的第二次尝试

List<Object> list = map.computeIfAbsent("key", ArrayList::new);
Run Code Online (Sandbox Code Playgroud)

实际上等于

List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
Run Code Online (Sandbox Code Playgroud)

并且因为ArrayList没有构造函数将String作为参数,所以它不起作用.第一个示例工作,因为它创建一个包含一个元素的列表.