假设我有一个Map<Integer, List<Integer>> map = new HashMap<>();
的HashMap。
现在List<Integer> values = computeIfAbsent(key, ArrayList::new);
可以正常工作,但是List<Integer> values = computeIfAbsent(key, LinkedList::new);
会引发编译错误。
我可以在ArrayList和LinkedList中看到no-arg构造函数。 我在这里想念的是什么,有人可以解释这种现象吗?
答案 0 :(得分:7)
您可能打算做的是将要初始化的lamba表达式指定为:
List<Integer> values = map.computeIfAbsent(key, a -> new ArrayList<>());
或
List<Integer> values = map.computeIfAbsent(key, a -> new LinkedList<>());
原因,为什么要代码
List<Integer> values = computeIfAbsent(key, LinkedList::new);
不会编译为最接近当前语法且带有单个参数的构造函数期望使用Collection<? extends E> c
而不是Integer
,因此无法解决。
另一方面,原因
List<Integer> values = map.computeIfAbsent(key, ArrayList::new);
编译是,它有一个constructor accepting int
argument,但请注意,它表示列表的容量。
答案 1 :(得分:3)
所需的lambda必须具有签名Function<? super K,? extends V> mappingFunction
,因此在您编写时:
List<Integer> values = map.computeIfAbsent(key, ArrayList::new);
必须提供一个构造函数,该构造函数的类型必须与key
(Integer
)中的一个兼容。 ArrayList
有一个,而LinkedList
没有一个:
ArrayList
的构造函数:
ArrayList()
ArrayList(Collection c)
ArrayList(int initialCapacity)
LinkedList
的构造函数:
LinkedList()
LinkedList(集合c)
请注意,它适用于ArrayList
的事实可能不是一个好主意,因为它构造了一个初始容量为空的ArrayList
(可能会导致奇怪的边界)效果)。
您可以参考Method reference in Java。
答案 2 :(得分:0)
使用以下命令
List<Integer> values = map.computeIfAbsent(key, x -> new ArrayList<>());