[英]Argument Mismatch when using the collect Stream method
The following code: 以下代码:
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);
generates the following error during compilation: 编译期间生成以下错误:
List namesAsList = names.collect(() -> new ArrayList(),List::add,List::add); 列表namesAsList = names.collect(() - > new ArrayList(),List :: add,List :: add); ^ (argument mismatch; invalid method reference incompatible types: ArrayList cannot be converted to int) where R,T are type-variables: R extends Object declared in method collect(Supplier,BiConsumer,BiConsumer) T extends Object declared in interface Stream 1 error ^(参数不匹配;无效方法引用不兼容类型:ArrayList不能转换为int)其中R,T是类型变量:R extends方法中声明的对象collect(Supplier,BiConsumer,BiConsumer)T扩展在接口Stream 1中声明的Object错误
When I amend the code to remove the generic the code compiles with an unchecked expression warning: 当我修改代码以删除泛型时,代码将使用未经检查的表达式警告进行编译:
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);
Why would I be receiving this error? 为什么我会收到此错误? I do not expect the problem to be relating to an int. 我不认为这个问题与int有关。
If the answer could include the way of figuring out the issue, this will be appreciated, so I can learn how to solve these problems myself. 如果答案可以包括解决问题的方法,我将不胜感激,所以我可以自己学习如何解决这些问题。
The method reference passed for combiner
does not really fit. 为combiner
传递的方法引用并不真正适合。 Try: 尝试:
List<String> namesAsList = names
.collect(ArrayList::new, List::add, List::addAll);
You passed the List::add
and compiler is doing its best to try to interpret it as a combiner instance of BiConsumer
type. 您传递了List::add
,编译器正在尽力将其解释为BiConsumer
类型的组合器实例。 Hence, the weird argument mismatch error. 因此,奇怪的参数不匹配错误。
Also, I assume you are implementing this only for research purposes. 此外,我假设您仅为研究目的实施此操作。 If you want to collect a Stream
to a List
, you can simply use: 如果要将Stream
收集到List
,可以使用:
.collect(Collectors.toList());
If you want to collect you Stream
to ArrayList
specifically, you can go for: 如果你想专门收集Stream
到ArrayList
,你可以去:
.collect(Collectors.toCollection(ArrayList::new));
The problem is in the combiner
, specifically: List::add
should really be List::addAll
. 问题出在combiner
,具体来说: List::add
应该是List::addAll
。
Or more readable like this: 或者更像这样的可读性:
List<String> namesAsList = names.collect(
() -> new ArrayList<>(),
List::add,
List::addAll);
You can re-write that with lambda expression when you are un-sure btw: 当你不确定btw时,你可以用lambda表达式重写它:
List<String> namesAsList = names.collect(
() -> new ArrayList<>(),
List::add,
(List<String> left, List<String> right) -> {
left.addAll(right);
});
Notice that there are other problems as-well, like () -> new ArrayList<String>()
, the type will be inferred by the compiler here, so no need for a <String>
, like this: () -> new ArrayList<>()
. 请注意,还有其他问题,如() -> new ArrayList<String>()
,这里的类型将由编译器推断,所以不需要<String>
,如下所示:( () -> new ArrayList<>()
。 Also this can be transformed to a method reference too: ArrayList::new
, so ultimately it would be even simpler: 此外,这也可以转换为方法引用: ArrayList::new
,所以最终它会更简单:
List<String> namesAsList = names.collect(
ArrayList::new,
List::add,
List::addAll);
This btw is the same thing that Collectors.toList
does internally, so even further this can be simplified to: 这个顺便说一句是Collectors.toList
在内部做的事情,所以更进一步,这可以简化为:
List<String> namesAsList = names.collect(Collectors.toList());
The only problem is that the specification is free to change that (to return any other List
besides ArrayList
), so it could be written: 唯一的问题是规范可以自由地改变它(除了返回ArrayList
之外的任何其他 List
),所以它可以写成:
List<String> namesAsList = names.collect(Collectors.toCollection(ArrayList::new));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.