为啥 flatMap 不将 Stream<Stream<SomeClass>> 扁平化到 SomeClass 而是扁平化到 Stream<SomeClass>?
Posted
技术标签:
【中文标题】为啥 flatMap 不将 Stream<Stream<SomeClass>> 扁平化到 SomeClass 而是扁平化到 Stream<SomeClass>?【英文标题】:Why flatMap doesn't flat Stream<Stream<SomeClass>> to the SomeClass but rather to Stream<SomeClass>?为什么 flatMap 不将 Stream<Stream<SomeClass>> 扁平化到 SomeClass 而是扁平化到 Stream<SomeClass>? 【发布时间】:2021-10-01 11:14:34 【问题描述】:我读到的关于 flatMap 的内容:
要了解扁平化流的含义,请考虑一个 像 [ [1,2,3],[4,5,6],[7,8,9] ] 这样的结构,它有“两个层次”。 展平这意味着将其转换为“一层”结构:[ 1,2,3,4,5,6,7,8,9]
import java.util.List;
import java.util.stream.Stream;
public class FlatMapDemo
List<Country> countries;
void demoFlatMap()
Stream<Stream<City>> streamStreamCity = countries
.stream()
.map(country -> country.cities.stream());
streamStreamCity.flatMap(cityStream -> /*it's not City, it's Stream<City> !!!*/);
class Country
List<City> cities;
class City
int population;
所以我只想计算来自所有国家的所有人口,但城市人口超过 1000 人。所以我创建了Stream<Stream<City>>
并希望flatMap flat 为我Stream<Stream
并给我City 类采取类似:.flatMap(city -> city.population)
过滤后:.filter(population > 1000)
但似乎我错了。请解释为什么 flatMap 不这样做?不就是扁平化的目的吗?
【问题讨论】:
不需要将flatMap拆分为单独的操作,可以在map()方法之后继续拆分。您将其从 StreamStream<Stream<City>>
,我的问题是:为什么flatMap
没有从Stream<Stream<City>>
到达City
?
所以:int sum = streamStreamCity.flatMap(cityStream -> cityStream) .filter(city -> city.population > 1000) .mapToInt(city -> city.population) .sum();
- 对吧?
flatMap
操作将流的流扁平化为单个流。如果我正确理解你想要什么,你应该做int totalPopulation = countries.stream().flatMap(country -> country.cities.stream()).mapToInt(city -> city.population).filter(population -> population > 1000).sum()
。
这能回答你的问题吗? What's the difference between map() and flatMap() methods in Java 8?
【参考方案1】:
flatMap()
的目标不是对 Stream<Stream<A>>
的 A
项应用转换。如果您最终得到这样的类型,则很可能表明您在某处误用了 map()
操作。
flatMap()
的目标是将Stream<A>
转换为Stream<B>
,当您有一个函数f
可以从单个A
元素生成Stream<B>
(简化一点,它是Function<A, Stream<B>>
)。 IE。它通过避免以嵌套流结束来“扁平化”流。
你会像这样使用它
getStreamOfA().flatMap(f) // returns Stream<B>
所以在你的例子中:
Stream<City> cityStream = countries
.stream()
.flatMap(country -> country.cities.stream());
【讨论】:
以上是关于为啥 flatMap 不将 Stream<Stream<SomeClass>> 扁平化到 SomeClass 而是扁平化到 Stream<SomeClass>?的主要内容,如果未能解决你的问题,请参考以下文章
java8 stream流操作的flatMap(流的扁平化)