[英]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)操作。 中间操作总是懒惰的。
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.