Intellij idea 如何将流收集到CopyOnWriteArrayList中

Intellij idea 如何将流收集到CopyOnWriteArrayList中,intellij-idea,java-8,java-stream,collectors,Intellij Idea,Java 8,Java Stream,Collectors,我得到了“不兼容的类型,必需的:CopyOnWriteArrayList,找到的:Object”,如下所示。我正在使用IntelliJ 2016.1.1 CopyOnWriteArrayList<Foo> l = fields.stream() .distinct() .collect(toCollection(CopyOnWriteArra

我得到了“不兼容的类型,必需的:CopyOnWriteArrayList,找到的:Object”,如下所示。我正在使用IntelliJ 2016.1.1

CopyOnWriteArrayList<Foo> l = fields.stream()
                                    .distinct()
                                    .collect(toCollection(CopyOnWriteArrayList::new));
CopyOnWriteArrayList l=fields.stream()
.distinct()
.collect(toCollection(CopyOnWriteArrayList::new));

这就像您的字段对象不是Foo类型一样,否则它应该可以在下面的工作代码中找到

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

public class Foo {


    private String name;

    Foo(String name){

        this.name=name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Foo [name=" + name + "]";
    }

    public static void main(String[] args) {
        List<Foo> fields = new ArrayList<>();
        fields.add(new Foo("aa"));
        fields.add(new Foo("bb"));
        CopyOnWriteArrayList<Foo> l = fields.stream().distinct().collect(Collectors.toCollection(CopyOnWriteArrayList::new));

        System.out.println("l"+l);
    }


}
import java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.CopyOnWriteArrayList;
导入java.util.stream.collector;
公开课Foo{
私有字符串名称;
Foo(字符串名){
this.name=name;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
@凌驾
公共字符串toString(){
返回“Foo[name=“+name+”]”;
}
公共静态void main(字符串[]args){
列表字段=新的ArrayList();
字段。添加(新Foo(“aa”);
字段。添加(新Foo(“bb”);
CopyOnWriteArrayList l=fields.stream().distinct().collect(Collectors.toCollection(CopyOnWriteArrayList::new));
系统输出打印项次(“l”+l);
}
}

PS:如果您的字段是非泛型的,那么这也会产生错误,就像您的字段对象不是Foo类型一样,否则应该可以在下面的工作代码中找到

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

public class Foo {


    private String name;

    Foo(String name){

        this.name=name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Foo [name=" + name + "]";
    }

    public static void main(String[] args) {
        List<Foo> fields = new ArrayList<>();
        fields.add(new Foo("aa"));
        fields.add(new Foo("bb"));
        CopyOnWriteArrayList<Foo> l = fields.stream().distinct().collect(Collectors.toCollection(CopyOnWriteArrayList::new));

        System.out.println("l"+l);
    }


}
import java.util.ArrayList;
导入java.util.List;
导入java.util.concurrent.CopyOnWriteArrayList;
导入java.util.stream.collector;
公开课Foo{
私有字符串名称;
Foo(字符串名){
this.name=name;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
@凌驾
公共字符串toString(){
返回“Foo[name=“+name+”]”;
}
公共静态void main(字符串[]args){
列表字段=新的ArrayList();
字段。添加(新Foo(“aa”);
字段。添加(新Foo(“bb”);
CopyOnWriteArrayList l=fields.stream().distinct().collect(Collectors.toCollection(CopyOnWriteArrayList::new));
系统输出打印项次(“l”+l);
}
}

PS:如果您的字段是非泛型的,那么这也会产生错误

问题是
字段
的类型不合适,很可能是原始类型,这会将流链的泛型调用变成返回其已擦除类型的未检查操作,这是终端
collect
呼叫的
Object

使用正确的类型,这项工作不会出现问题,即

List<String> fields=Arrays.asList("foo", "bar", "baz", "foo");
CopyOnWriteArrayList<String> l =
    fields.stream()
          .distinct()
          .collect(Collectors.toCollection(CopyOnWriteArrayList::new));
请注意,在这种特定情况下,
distinct
会在幕后隐式地构建一个
,因此我们可以通过构建
来明显地代替临时
列表
,并删除
distinct
步骤来提高性能:

CopyOnWriteArrayList<String> l =
    fields.stream()
          .collect(Collectors.collectingAndThen(
                              Collectors.toCollection(LinkedHashSet::new),
                              CopyOnWriteArrayList::new));
CopyOnWriteArrayList l=
fields.stream()
收集,收集收集,然后收集(
collector.toCollection(LinkedHashSet::new),
CopyOnWriteArrayList::new));
由此得出的结论是,对于这个特定的用例,我们可以让它变得更简单,甚至可能更高效:

CopyOnWriteArrayList<String> l = new CopyOnWriteArrayList<>(new LinkedHashSet<>(fields));
CopyOnWriteArrayList l=新的CopyOnWriteArrayList(新的LinkedHashSet(字段));

问题在于,
字段
的类型不合适,很可能是原始类型,这会将流链的一般调用转化为未经检查的操作,返回其已擦除的类型,即终端
collect
调用的
对象

使用正确的类型,这项工作不会出现问题,即

List<String> fields=Arrays.asList("foo", "bar", "baz", "foo");
CopyOnWriteArrayList<String> l =
    fields.stream()
          .distinct()
          .collect(Collectors.toCollection(CopyOnWriteArrayList::new));
请注意,在这种特定情况下,
distinct
会在幕后隐式地构建一个
,因此我们可以通过构建
来明显地代替临时
列表
,并删除
distinct
步骤来提高性能:

CopyOnWriteArrayList<String> l =
    fields.stream()
          .collect(Collectors.collectingAndThen(
                              Collectors.toCollection(LinkedHashSet::new),
                              CopyOnWriteArrayList::new));
CopyOnWriteArrayList l=
fields.stream()
收集,收集收集,然后收集(
collector.toCollection(LinkedHashSet::new),
CopyOnWriteArrayList::new));
由此得出的结论是,对于这个特定的用例,我们可以让它变得更简单,甚至可能更高效:

CopyOnWriteArrayList<String> l = new CopyOnWriteArrayList<>(new LinkedHashSet<>(fields));
CopyOnWriteArrayList l=新的CopyOnWriteArrayList(新的LinkedHashSet(字段));

猜猜看:也许你需要一个类型提示,比如
Collections.toCollection()
或者类似的东西。现在我想知道为什么投票被否决了。我已经尽了我的力量去修复它了。不会有帮助的。这里还有一些字符。你能告诉我fields变量是什么吗?这可以用JavaC1.8.052编译。尝试升级Intellij。猜猜看:也许你需要一个类型提示,比如
Collections.toCollection()
或类似的东西。现在我想知道为什么投票被否决了。我已经尽了我的力量去修复它了。不会有帮助的。这里还有一些字符。你能告诉我fields变量是什么吗?这可以用JavaC1.8.052编译。尝试升级Intellij。