以下代码:
names = Arrays.asList("A","B","C").stream();
List<String> namesAsList = names.collect(() -> new ArrayList<String>(),List::add,List::add);
System.out.println("Individual Strings put into a list: " + namesAsList);
在编译期间生成以下错误:
列出namesAsList = names.collect(() - &gt; new 的ArrayList(),列表::添加,列表::补充); ^(参数不匹配;无效方法引用不兼容类型:ArrayList不能 转换为int)其中R,T是类型变量:R扩展Object 在方法collect(Supplier,BiConsumer,BiConsumer)中声明T扩展在接口Stream 1中声明的Object 错误
当我修改代码以删除泛型时,代码将使用未经检查的表达式编译警告:
Stream<String> names = Arrays.asList("A","B","C").stream();
List<String> namesAsList = names.collect(() -> new ArrayList(),List::add,List::add);
System.out.println("Individual Strings put into a list: " + namesAsList);
为什么我会收到此错误?我不认为这个问题与int有关。
如果答案可能包括解决问题的方法,我将不胜感激,所以我可以自己学习如何解决这些问题。
答案 0 :(得分:7)
为combiner
传递的方法引用并不适合。
尝试:
List<String> namesAsList = names
.collect(ArrayList::new, List::add, List::addAll);
您传递了List::add
,编译器正在尽力将其解释为BiConsumer
类型的组合器实例。因此,奇怪的参数不匹配错误。
此外,我假设您仅为研究目的实施此操作。如果您想将Stream
收集到List
,只需使用:
.collect(Collectors.toList());
如果您想特别向Stream
收集ArrayList
,您可以选择:
.collect(Collectors.toCollection(ArrayList::new));
答案 1 :(得分:6)
问题出在combiner
,具体来说:List::add
应该是List::addAll
。
或更具可读性:
List<String> namesAsList = names.collect(
() -> new ArrayList<>(),
List::add,
List::addAll);
当你不确定btw:
时,你可以用lambda表达式重写它List<String> namesAsList = names.collect(
() -> new ArrayList<>(),
List::add,
(List<String> left, List<String> right) -> {
left.addAll(right);
});
请注意,还有其他问题,例如() -> new ArrayList<String>()
,编译器会在此处推断出类型,因此不需要<String>
,如下所示:() -> new ArrayList<>()
。此外,这也可以转换为方法参考:ArrayList::new
,所以最终它会更简单:
List<String> namesAsList = names.collect(
ArrayList::new,
List::add,
List::addAll);
这个btw与Collectors.toList
内部做的相同,所以更进一步,这可以简化为:
List<String> namesAsList = names.collect(Collectors.toList());
唯一的问题是规范可以自由更改(除了List
之外还返回任何其他 ArrayList
),因此可以写成:
List<String> namesAsList = names.collect(Collectors.toCollection(ArrayList::new));