Java 流收集方法的有效供应商

Java 流收集方法的有效供应商,java,arraylist,java-8,java-stream,collectors,Java,Arraylist,Java 8,Java Stream,Collectors,我只是想创建一些类似于我自己的Collectors.toList(),但似乎不起作用 import java.util.ArrayList; public class ShipmentTracingDTO { boolean destination = false; public ShipmentTracingDTO(Boolean destination) { this.destination = destination; } public ShipmentTracingDTO

我只是想创建一些类似于我自己的
Collectors.toList()
,但似乎不起作用

import java.util.ArrayList;

public class ShipmentTracingDTO {

boolean destination = false;

public ShipmentTracingDTO(Boolean destination) {
    this.destination = destination;
}

public ShipmentTracingDTO() {
}

public static void main(String[] args) {
    ArrayList<ShipmentTracingDTO> tracings = new ArrayList<>();
    tracings.add(new ShipmentTracingDTO(true));
    tracings.add(new ShipmentTracingDTO(true));
    tracings.add(new ShipmentTracingDTO(false));
    tracings.add(new ShipmentTracingDTO(false));
    ArrayList<ShipmentTracingDTO> newTracings = new ArrayList<>();

// Error coming for ArrayList::new : The constructed object of type ArrayList is 
//incompatible with the descriptor's return type: R

    tracings.stream().collect(ArrayList::new, (left, right) -> left.add(right), (left, right) -> {
        left.addAll(right);
        return left;
    });
}

private boolean getDestination() {

    return destination;
}
import java.util.ArrayList;
公共类ShipmentTracingDTO{
布尔目标=false;
公共ShipmentTracingDTO(布尔目标){
this.destination=目的地;
}
公共装运跟踪到(){
}
公共静态void main(字符串[]args){
ArrayList跟踪=新建ArrayList();
添加(新ShipmentTracingDTO(true));
添加(新ShipmentTracingDTO(true));
添加(新发货跟踪到(假));
添加(新发货跟踪到(假));
ArrayList newRacings=新的ArrayList();
//ArrayList::new出现错误:ArrayList类型的构造对象为
//与描述符的返回类型不兼容:R
tracings.stream().collect(ArrayList::new,(左,右)->left.add(右)(左,右)->{
左。addAll(右);
左转;
});
}
私有布尔getDestination(){
返回目的地;
}
}


我的问题是如果
ArrayList::new
在这里不起作用,那么什么会起作用。我尝试了不同的变体,但似乎都不起作用

您似乎在寻找:

tracings.stream()
        .collect(ArrayList::new, 
                 ArrayList::add, 
                 ArrayList::addAll);
与lambda表示法相同:

tracings.stream()
        .collect(ArrayList::new, 
                 (left, right) -> left.add(right), 
                 (left, right) -> left.addAll(right)); // notice no 'return'

Reason:需要一个
BiConsumer
作为参数,它有一个带有
void
返回类型的
accept
方法。

只需这样更改它

tracings.stream().collect(ArrayList::new, (left, right) -> left.add(right), (left, right) -> {
    left.addAll(right);
});
您需要的是
BiConsumer
而不是
BinaryOperator
。上面传递的是一个
二进制运算符

BinaryOperator<List<Integer>> s = (left, right) -> {
            left.addAll(right);
            return left;
};
下面是一个示例
BinaryOperator

BinaryOperator<List<Integer>> s = (left, right) -> {
            left.addAll(right);
            return left;
};
我只是想创造一些类似于收藏家的东西 我自己的,但似乎不起作用

import java.util.ArrayList;

public class ShipmentTracingDTO {

boolean destination = false;

public ShipmentTracingDTO(Boolean destination) {
    this.destination = destination;
}

public ShipmentTracingDTO() {
}

public static void main(String[] args) {
    ArrayList<ShipmentTracingDTO> tracings = new ArrayList<>();
    tracings.add(new ShipmentTracingDTO(true));
    tracings.add(new ShipmentTracingDTO(true));
    tracings.add(new ShipmentTracingDTO(false));
    tracings.add(new ShipmentTracingDTO(false));
    ArrayList<ShipmentTracingDTO> newTracings = new ArrayList<>();

// Error coming for ArrayList::new : The constructed object of type ArrayList is 
//incompatible with the descriptor's return type: R

    tracings.stream().collect(ArrayList::new, (left, right) -> left.add(right), (left, right) -> {
        left.addAll(right);
        return left;
    });
}

private boolean getDestination() {

    return destination;
}
虽然其他答案指定了您做错了什么,但值得注意的是,如果您试图创建类似于
toList()
的内容,但同时指定返回的列表类型,那么我建议使用专门为此目的而设计的
toCollection

tracings.stream().collect(Collectors.toCollection(ArrayList::new));
尽管这并不比:

new ArrayList<>(tracings);
newarraylist(跟踪);

它更简短,可读性更强。

(左,右)->left.add(右)
可以被
List::add
(左,右)->left.add(右)
替换为
List::addAll
。是的,但它与问题没有直接关系。OP问到“什么会起作用”。方法引用将与lambdas一样工作。但我更愿意在解释的同时展示最佳实践,而不仅仅是解决编译问题。@ETO我已经根据建议更新了答案。这基本上就是
Collectors.toList()
在内部所做的,尽管规范给了它不同的空间(也就是说,不是返回一个
ArrayList
,而是返回另一个
List
实现)。但是当您使用
Collector.toCollection(ArrayList::new)
时,您得到的正是这一点。混淆可能源于
Collector.of(…)
的合并函数是一个二进制运算符:
tracings.stream().Collector(Collector.of(ArrayList::new,List::add,(l,r)->{l.addAll(r);return l;})
。这允许潜在的优化,即
(l,r)->{if(l.isEmpty())返回r;l.addAll(r);return l;}