繁体   English   中英

为什么 flatMap 接受一个返回 stream 而不是 Collection 的 function?

[英]Why does flatMap take in a function that returns stream instead of Collection?

为什么 flatMap 操作需要返回 Stream 的 function 而不是返回 Collection 的 function? 它强制用户手动进行 stream 转换的任何特殊原因?

阅读源代码示例,我可以看到通过这种方式可以将兼容性扩展到 arrays 但 flatMap 的重载不会达到相同的结果吗?

// Java 8 source code example:
Stream<String> words = lines.flatMap(line -> Stream.of(line.split(" +")));

在哪些用例中最好明确显示流式传输过程?

示例:为什么我被迫这样做

Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> flatList = map.entrySet().stream().flatMap(e -> e.getValue().stream()).collect(Collectors.toList());

而不是这个?

Map<String, List<String>> map = new HashMap<String, List<String>>();
List<String> flatList = map.entrySet().stream().flatMap(Map.Entry::getValue).collect(Collectors.toList());

为什么flatMap()操作需要返回Stream的 function 而不是返回Collection的 function?

原因有很多:

  • Stream 是一种迭代方式,即我们没有将数据存储在 stream 中,它的目的是对数据源进行惰性迭代,可以是String 、 Array 、 IO-Stream 等。

  • 其次, Stream 操作分为两组:终端操作,用于产生结果并终止 stream 管道的执行(即不可能在终端操作之后应用任何操作),以及中间操作,它转换 stream . 中间操作总是懒惰的。 stream 一个一个地从源中获取元素并延迟处理它们,即仅在需要时才进行操作。 不要使用带有嵌套for循环链的新 stream,它们的行为不同。 每个中间操作都会产生一个新的 stream。

这是API 文档中的引述:

流在几个方面不同于 collections:

  • 没有存储 stream不是存储元素的数据结构 相反,它通过计算操作的管道从源(例如数据结构、数组、生成器 function 或 I/O 通道)传送元素。

  • 懒惰寻求 许多 stream 操作,如过滤、映射或重复删除,可以延迟实现,从而提供优化机会。 例如,“查找第一个包含三个连续元音的字符串”不需要检查所有输入字符串。 Stream 操作分为中间(Stream-producing)操作和终端(value-or side-effect-producing)操作。 中间操作总是懒惰的。

  • 由于 Stream 是数据源的内部迭代器,它可以具有不同的性质(不一定是Collectoin ),因此flatMap()期望数据具有可预测的统一形状是合理的,而不是数组、集合、可迭代等,而是另一个内部迭代器,即另一个 Stream,所以很明显如何处理它。

您可以使用的任何选项都不那么直观。 如果flatMap()以这样的方式实现,那么它会期望 function 生成Collection你将如何处理字符串、arrays、IO-Streams、 Iterable的各种实现? 通过将数据转储到集合中——这不是一种选择。 如果我们想象flatMap()需要Iterable ,也会出现同样的问题,我们如何从String生成Iterable Streams 被设计成多功能的。

我怀疑你对flatMap()的判断有偏差,因为你不习惯。 当您接受Stream 是一个内部迭代器的想法时,扁平化数据的操作期望 function 产生另一个迭代器这一事实会被认为更直观。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM