我认为使用flatMap()编写的所有流管道都可以转换为mapMulti。看起来,当flatMap()或mapMulti()返回/在无限流上运行时,我错了。
注:这只是为了教育目的
当我们将一个元素映射到一个flatMap()中的无限流,然后是一个limit(),则流管道是惰性的,并根据所需的元素数进行计算。
list.stream()
.flatMap(element -> Stream.generate(() -> 1))
.limit(3)
.forEach(System.out::println);输出:
1
1
1但是,在mapMulti()中执行同样的操作时,管道仍然是惰性,也就是说,它不会消耗无限流。但是在IDE (Intellij)中运行时,它会挂起,不会终止(我猜等待其他元素的消耗),并且不会从流管道执行中出来。
用mapMulti(),
list.stream()
.mapMulti((element, consumer) -> {
Stream.generate(() -> 1)
.forEach(consumer);
})
.limit(3)
.forEach(System.out::println);
System.out.println("Done"); //Never gets here输出:
1
1
1但是最后的打印(Done)没有被执行。
这是预期的行为吗?我在Javadoc中的无限流和mapMulti()上找不到任何警告或点。
发布于 2022-11-17 13:37:16
mapMulti()的优点是它使用成为流一部分的新元素,取代初始元素(与flatMap()相反,后者在内部为每个元素生成一个新流)。如果您正在生成一个具有mapMulti()内部终端操作的完全成熟的流,则应该执行它。您已经创建了一个无法终止的无限流(正如@Lino在评论中所指出的那样)。
相反,flatMap()期望一个函数产生流,即函数只返回它而不是进程。
下面引用了API注记的一句话,强调了这两个操作之间的区别:
API备注: 该方法与
flatMap类似,它对流的元素进行一对多的转换,并将结果元素平放为新的流。在以下情况下,此方法比flatMap更可取:
flatMap的要求,使用这种方法可以避免为每个结果元素组创建一个新的Stream实例的开销。https://stackoverflow.com/questions/74476209
复制相似问题