【问题标题】:What kind of List<E> does Collectors.toList() return?Collectors.toList() 返回什么样的 List<E>?
【发布时间】:2014-03-21 15:53:29
【问题描述】:

我正在阅读State of the Lambda: Libraries Edition,并且对一个声明感到惊讶:

Streams 部分下,有以下内容:

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

文档没有说明shapes 究竟是什么,我也不知道它是否重要。

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

  • 它将变量分配给List&lt;Shape&gt;,这完全没问题。
  • stream()filter() 决定使用哪种列表。
  • Collectors.toList() 没有指定List 的具体类型。

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

【问题讨论】:

  • 由于toUnmodifiableList()方法是在Java 10中加入的,看来toList()的可变性现在可以得到保证了。

标签: java list lambda java-8 collectors


【解决方案1】:

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

如果您查看 Collectors#toList() 的文档,它会指出 - “无法保证返回的 List 的类型、可变性、可序列化性或线程安全性”。如果您希望返回特定的实现,可以改用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&lt;Shape&gt; 实现。

更新

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

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

【讨论】:

  • 你知道,你可以把 Supplier 写成 lambda :)
  • .collect(Collectors.toCollection(LinkedList&lt;Shape&gt;::new)) 也可以吗?
  • @skiwi 或者使用显式类型参数更好:Collectors.&lt;Shape, List&lt;Shape&gt;&gt;toCollection(LinkedList&lt;Shape&gt;::new)
  • @panos unmodifiableList 是一个“Claytons 不可变”,但如果你想要一个实际不可变的集合,你最终会编写自己的收集器,例如番石榴之一。不过稍微想一想,真正的遗憾是 toList() 并没有首先返回一个不可变的列表。
  • @Trejkaz 同意,toList 一开始就应该返回一个不可变的,但是哦,它没有。我们希望在某个时候改变这一点。另外,什么是“Claytons 不可变”?
【解决方案2】:

通过 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);
}

【讨论】:

  • 请记住,这只是 API 的一种潜在实现。 :)
  • @Trejkaz 正确。事实上,我们正在认真考虑在某个时候改变实现。
【解决方案3】:

没关系,但具体类型是非泛型的,因为实际上所有类型在运行时都是非泛型的。

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    • 2017-12-16
    • 2018-01-24
    • 2019-12-09
    • 1970-01-01
    • 2011-09-04
    相关资源
    最近更新 更多