Java 什么样的列表<;E>;Collectors.toList()是否返回?

Java 什么样的列表<;E>;Collectors.toList()是否返回?,java,list,lambda,java-8,collectors,Java,List,Lambda,Java 8,Collectors,我正在读一篇文章,对其中的一句话感到惊讶: 在“流”部分下,有以下内容: List<Shape> blue = shapes.stream() .filter(s -> s.getColor() == BLUE) .collect(Collectors.toList()); List blue=shapes.stream() .filter(s->s.getColor()==蓝

我正在读一篇文章,对其中的一句话感到惊讶:

在“流”部分下,有以下内容:

List<Shape> blue = shapes.stream()
                         .filter(s -> s.getColor() == BLUE)
                         .collect(Collectors.toList());
List blue=shapes.stream()
.filter(s->s.getColor()==蓝色)
.collect(Collectors.toList());
文档没有说明什么是
形状
,我甚至不知道这是否重要

让我困惑的是:这段代码返回什么样的具体
List

  • 它将变量分配给一个
    列表
    ,这是完全正确的
  • stream()
    filter()
    决定使用哪种列表
  • Collectors.toList()
    都没有指定
    列表的具体类型

那么,这里使用的是
列表的具体的类型(子类)?有什么保证吗?

这无关紧要,但具体类型是非泛型的,因为实际上所有类型在运行时都是非泛型的

那么,这里使用的是列表的什么具体类型(子类)?有什么保证吗

我不这么认为,但ArrayList或LinkedList似乎很有可能

那么,这里使用的是列表的什么具体类型(子类)?有什么保证吗

如果您查看的文档,它会声明“对于返回的列表的类型、可变性、序列化性或线程安全性没有任何保证”。如果希望返回特定的实现,可以使用

Supplier=()->new LinkedList();
List blue=shapes.stream()
.filter(s->s.getColor()==蓝色)
.收集(收集器.收集(供应商));
从lambda中,您可以返回您想要的
列表的任何实现

更新

或者,您甚至可以使用方法引用:

List<Shape> blue = shapes.stream()
            .filter(s -> s.getColor() == BLUE)
            .collect(Collectors.toCollection(LinkedList::new));
List blue=shapes.stream()
.filter(s->s.getColor()==蓝色)
.collect(Collectors.toCollection(LinkedList::new));

在Netbeans中导航(Ctrl+单击),我在这段代码中登陆。它似乎使用ArrayList作为供应商

public static <T> Collector<T, ?, List<T>> toList() {
    return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                               (left, right) -> { left.addAll(right); return left; },
                               CH_ID);
}
公共静态收集器toList(){
返回新的CollectorImpl((供应商)ArrayList::new,List::add,
(左,右)->{left.addAll(右);返回left;},
(中华人民共和国),;
}

你知道,你可以把供应商写成lambda:)将
收集(collector.toCollection(LinkedList::new))
也可以工作?@skiwi或者更好地使用显式类型参数:
collector.toCollection(LinkedList::new)
@panos unmodifiableList是一个“克莱顿不变的”,但是,如果你想要一个实际上不可变的集合,例如番石榴的集合,那么你最终会编写自己的收集器。但是仔细想想,真正的遗憾是toList()一开始并没有返回一个不可变的列表。@Trejkaz同意,toList一开始就应该返回一个不可变的列表,但哦,好吧,它没有。我们希望在某个时候改变这一点。另外,什么是“Claytons不可变”?请记住,这只是API的一个潜在实现:@特雷卡兹说得对。事实上,我们正在认真考虑在某个时候更改实现。由于Java 10中添加了
toUnmodifiableList()
方法,现在似乎可以保证
toList()
的可变性。
public static <T> Collector<T, ?, List<T>> toList() {
    return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                               (left, right) -> { left.addAll(right); return left; },
                               CH_ID);
}