简体   繁体   English

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

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

Why does the flatMap operation require a function which returns Stream instead of a function that returns a Collection?为什么 flatMap 操作需要返回 Stream 的 function 而不是返回 Collection 的 function? Any particular reason it forces the user to do the stream conversion manually?它强制用户手动进行 stream 转换的任何特殊原因?

Reading the source code example I can see that this way the compatibilioty can be extended to arrays but wouldn't an overload of flatMap achieve the same result?阅读源代码示例,我可以看到通过这种方式可以将兼容性扩展到 arrays 但 flatMap 的重载不会达到相同的结果吗?

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

What are the use cases where it's better to have the streaming process explicited?在哪些用例中最好明确显示流式传输过程?

Example: why am I forced to do this示例:为什么我被迫这样做

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

instead of this?而不是这个?

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

Why does the flatMap() operation require a function which returns Stream instead of a function that returns a Collection ?为什么flatMap()操作需要返回Stream的 function 而不是返回Collection的 function?

There are many reasons for that:原因有很多:

  • Stream is a means of iteration , ie we're not storing the data in the stream, its purpose is to iterate lazily many over the source of data, which can be a String , Array, IO-Stream, etc. Stream 是一种迭代方式,即我们没有将数据存储在 stream 中,它的目的是对数据源进行惰性迭代,可以是String 、 Array 、 IO-Stream 等。

  • Secondly, Stream operations are divided into two groups: terminal , which are meant to produce the result and terminate the execution of the stream pipeline (ie it's not possible to apply any operation after a terminal one), and intermediate operations, which transform the stream. Intermediate operations are always lazy .其次, Stream 操作分为两组:终端操作,用于产生结果并终止 stream 管道的执行(即不可能在终端操作之后应用任何操作),以及中间操作,它转换 stream . 中间操作总是懒惰的。 A stream takes elements from the source one-by-one and processes them lazily , ie operations occur only when needed. stream 一个一个地从源中获取元素并延迟处理它们,即仅在需要时才进行操作。 Don't a new stream with a chain of nested for -loops, they act differently.不要使用带有嵌套for循环链的新 stream,它们的行为不同。 Every intermediate operation produces a new stream.每个中间操作都会产生一个新的 stream。

Here's a quote from the API documentation :这是API 文档中的引述:

Streams differ from collections in several ways:流在几个方面不同于 collections:

  • No storage .没有存储 A stream is not a data structure that stores elements; stream不是存储元素的数据结构 instead, it conveys elements from a source such as a data structure, an array, a generator function, or an I/O channel, through a pipeline of computational operations.相反,它通过计算操作的管道从源(例如数据结构、数组、生成器 function 或 I/O 通道)传送元素。

  • Laziness-seeking .懒惰寻求 Many stream operations, such as filtering, mapping, or duplicate removal, can be implemented lazily, exposing opportunities for optimization.许多 stream 操作,如过滤、映射或重复删除,可以延迟实现,从而提供优化机会。 For example, "find the first String with three consecutive vowels" need not examine all the input strings.例如,“查找第一个包含三个连续元音的字符串”不需要检查所有输入字符串。 Stream operations are divided into intermediate (Stream-producing) operations and terminal (value- or side-effect-producing) operations. Stream 操作分为中间(Stream-producing)操作和终端(value-or side-effect-producing)操作。 Intermediate operations are always lazy .中间操作总是懒惰的。

  • Since Stream are internal iterators over the source of data which can have a different nature ( not necessarily a Collectoin ) it's reasonable for flatMap() to expect data in a predictable uniform shape , not an Array, Collection, Iterable, etc. but another internal iterator, ie another Stream, so that's obvious how to deal with it.由于 Stream 是数据源的内部迭代器,它可以具有不同的性质(不一定是Collectoin ),因此flatMap()期望数据具有可预测的统一形状是合理的,而不是数组、集合、可迭代等,而是另一个内部迭代器,即另一个 Stream,所以很明显如何处理它。

Any option that you can up with would be less intuitive.您可以使用的任何选项都不那么直观。 If flatMap() was implemented in such a way so that it would expect a function producing Collection how would you deal with strings, arrays, IO-Streams, various implementations of Iterable ?如果flatMap()以这样的方式实现,那么它会期望 function 生成Collection你将如何处理字符串、arrays、IO-Streams、 Iterable的各种实现? By dumping the data into a Collection - that's not an option.通过将数据转储到集合中——这不是一种选择。 Same issue would arise if we imagine that flatMap() required Iterable , how would we produce Iterable from a String ?如果我们想象flatMap()需要Iterable ,也会出现同样的问题,我们如何从String生成Iterable Streams are designed to be versatile. Streams 被设计成多功能的。

I suspect that your judgement regarding flatMap() is biased because you are not accustomed to it.我怀疑你对flatMap()的判断有偏差,因为你不习惯。 When you embrace the idea that a Stream is an Internal Iterator , the fact that operation for flattening the data expect function producing another iterator would be perceived as more intuitive.当您接受Stream 是一个内部迭代器的想法时,扁平化数据的操作期望 function 产生另一个迭代器这一事实会被认为更直观。

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

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