简体   繁体   English

使用collect Stream方法时,参数不匹配

[英]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: 如果你想专门收集StreamArrayList ,你可以去:

.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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM