我得到了“不兼容的类型,必需的: CopyOnWriteArrayList,找到的: Object”。我使用的是IntelliJ 2016.1.1。
CopyOnWriteArrayList<Foo> l = fields.stream()
.distinct()
.collect(toCollection(CopyOnWriteArrayList::new));发布于 2016-09-22 03:34:20
问题是fields有一个不适当的类型,最有可能的是,它有一个原始类型,这会将流链的泛型调用转换为返回其擦除类型的未检查操作,对于终端collect调用,该类型为Object。
使用正确的类型,这没有问题,即
List<String> fields=Arrays.asList("foo", "bar", "baz", "foo");
CopyOnWriteArrayList<String> l =
fields.stream()
.distinct()
.collect(Collectors.toCollection(CopyOnWriteArrayList::new));很管用。但请注意,正如“写入时复制”这个名称所暗示的那样,以这种方式构建一个CopyOnWriteArrayList是相当昂贵的。在每次插入时复制整个内容会导致二次时间复杂度。
解决方案是在转换为所需的目标类型之前,收集到更适合增量构建的临时集合。复制步骤可能看起来像是开销,但与直接收集到CopyOnWriteArrayList中的二次复杂性相比,它是线性开销。
CopyOnWriteArrayList<String> l =
fields.stream()
.distinct()
.collect(Collectors.collectingAndThen(
Collectors.toList(), CopyOnWriteArrayList::new));请注意,在此特定情况下,distinct在幕后隐式构建Set,因此我们可以通过显式构建Set来替代临时List并删除distinct步骤来提高性能:
CopyOnWriteArrayList<String> l =
fields.stream()
.collect(Collectors.collectingAndThen(
Collectors.toCollection(LinkedHashSet::new),
CopyOnWriteArrayList::new));这导致的结论是,对于这个特定的用例,我们可以让它变得更简单,甚至可能更高效:
CopyOnWriteArrayList<String> l = new CopyOnWriteArrayList<>(new LinkedHashSet<>(fields));发布于 2016-09-21 16:15:24
它看起来像你的字段对象不是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);
}
}PS:如果你的字段是非泛型的,那么这也会给出错误
https://stackoverflow.com/questions/39610750
复制相似问题