为啥 Java 8 Stream 上没有直接存在 toList() [重复]

Posted

技术标签:

【中文标题】为啥 Java 8 Stream 上没有直接存在 toList() [重复]【英文标题】:Why toList() is not there directly on Java 8 Stream [duplicate]为什么 Java 8 Stream 上没有直接存在 toList() [重复] 【发布时间】:2015-10-08 16:26:18 【问题描述】:

我了解 Java 8 Stream 提供了.collect 方法来将 Stream 转换为我们选择的任何集合/数据结构,它本质上是非常通用的。了解 Stream 可能来自非集合对象/资源。但是从使用的角度来看,将 Stream 转换为 List / Set 是很自然的。

Stream 已经提供了toArray() 转换为数组的方法,那为什么不提供toList()toSet() 呢?

【问题讨论】:

Retrieving a List from Stream 密切相关。 这是界面污染和易用性之间的折衷。他们选择不更多地污染界面。添加 toList() 也会要求 toSet() 方法,然后是 toMap() 等,最终重复收集器的许多方法,并使 Stream 接口更加复杂和“污染”许多收集方法。 ***.com/questions/28782165/… toArray() 方法也可以很容易地实现为Collector。我想,出于效率原因,它直接添加到 Stream 接口:如果您的 Stream 已调整大小,您可以利用它预先分配精确大小的数组。这对于收集器来说目前是不可能的:他们无法提前获得流的大小。有一个 request 来解决这个问题,尽管在这个方向上似乎还没有做任何工作。 @TagirValeev 我有一个关于.toArray 的相关问题。为什么它返回 Object[] ,而不是 T[] 【参考方案1】:

因为你不知道List 的实现会是什么样子:

它会是可变的吗? 你能改变它的大小吗? 等等等等

其实even Collectors.toList() makes no guarantee:

不保证返回的 List 的类型、可变性、可序列化性或线程安全性;如果需要对返回的 List 进行更多控制,请使用 toCollection(Supplier)。

因此,提供一个通用的.toList() 方法将适合某些人的某些用法,但它永远无法适合所有人的所有用法。当然,Collectors.toSet() 也是如此。

然而,数组不是问题:你知道你可以用它们做什么。

【讨论】:

为什么这个论点适用于 toList Stream 方法而不是 toList() Collector 用于 Stream 的 collect 方法? @Eran 好吧,另一个原因是根据Stream 实现,您可能会返回具有不同特征的列表,除非方法的合同定义明确。因此,这个决定是有道理的恕我直言。

以上是关于为啥 Java 8 Stream 上没有直接存在 toList() [重复]的主要内容,如果未能解决你的问题,请参考以下文章

java stream 为啥不能重用

为啥新的 Java 8 流在 toArray 调用上返回一个对象数组?

为啥在执行 Java Stream 终端操作时对象没有被垃圾收集?

Java 8 的Lambda函数式接口Stream,都安排上了!

为啥 Stream.CopyTo 不直接写入文件?

java8-Stream流的创建