Collectors.toList() 返回哪种 List<E>?

2022-08-31 12:16:01

我正在阅读Lambda的状态:图书馆版,并对一个声明感到惊讶:

部分下,有以下内容:

List<Shape> blue = shapes.stream()
                         .filter(s -> s.getColor() == BLUE)
                         .collect(Collectors.toList());

该文件没有说明实际是什么,我不知道它是否重要。shapes

让我感到困惑的是:这个代码块返回什么样的具体?List

  • 它将变量赋给 a ,这完全没问题。List<Shape>
  • stream()也不决定使用哪种列表。filter()
  • Collectors.toList()两者都没有指定 的具体类型。List

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


答案 1

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

如果你看一下 Collectors#toList() 的文档,它指出 - “对返回的列表的类型、可变性、可序列化性或线程安全性没有保证”。如果要返回特定的实现,可以改用 Collectors#toCollection(Supplier)。

Supplier<List<Shape>> supplier = () -> new LinkedList<Shape>();

List<Shape> blue = shapes.stream()
            .filter(s -> s.getColor() == BLUE)
            .collect(Collectors.toCollection(supplier));

从 lambda 中,您可以返回所需的任何实现。List<Shape>

更新

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

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

答案 2

在 Netbeans 中导航(Ctrl + Click),我进入了这段代码。它似乎正在使用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);
}