为什么我不能使用LinkedList :: new?

时间:2019-03-07 07:20:27

标签: java java-8 method-reference

假设我有一个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构造函数。 我在这里想念的是什么,有人可以解释这种现象吗?

3 个答案:

答案 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);

必须提供一个构造函数,该构造函数的类型必须与keyInteger)中的一个兼容。 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<>());