【问题标题】: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&lt;Stream&lt;City&gt;&gt; 并希望flatMap flat 为我Stream&lt;Stream 并给我City 类采取类似:.flatMap(city -&gt; city.population) 过滤后:.filter(population &gt; 1000) 但似乎我错了。请解释为什么 flatMap 不这样做?不就是扁平化的目的吗?

【问题讨论】:

  • 不需要将flatMap拆分为单独的操作,可以在map()方法之后继续拆分。您将其从 Stream 扁平化为 Stream,因此现在您可以添加过滤器,如 filter(county.getPopulation() > 1000) 和一个谓词,该谓词将过滤具有 > 1000 居民的城市,然后使用终端操作收集(Collectors.counting());最后将返回与上述谓词匹配的记录数。
  • 我拆分它只是为了暴露变量的类型:Stream&lt;Stream&lt;City&gt;&gt;,我的问题是:为什么flatMap 没有从Stream&lt;Stream&lt;City&gt;&gt; 到达City
  • 所以:int sum = streamStreamCity.flatMap(cityStream -&gt; cityStream) .filter(city -&gt; city.population &gt; 1000) .mapToInt(city -&gt; city.population) .sum(); - 对吧?
  • flatMap 操作将流的流扁平化为单个流。如果我正确理解你想要什么,你应该做int totalPopulation = countries.stream().flatMap(country -&gt; country.cities.stream()).mapToInt(city -&gt; city.population).filter(population -&gt; population &gt; 1000).sum()

标签: java java-8 java-stream flatmap


【解决方案1】:

flatMap() 的目标不是对 Stream&lt;Stream&lt;A&gt;&gt;A 项应用转换。如果您最终得到这样的类型,则很可能表明您在某处误用了 map() 操作。

flatMap() 的目标是将Stream&lt;A&gt; 转换为Stream&lt;B&gt;,当您有一个函数f 可以从单个A 元素生成Stream&lt;B&gt;(简化一点,它是Function&lt;A, Stream&lt;B&gt;&gt;)。 IE。它通过避免以嵌套流结束来“扁平化”流。

你会像这样使用它

getStreamOfA().flatMap(f) // returns Stream<B>

所以在你的例子中:

Stream<City> cityStream = countries
                .stream()
                .flatMap(country -> country.cities.stream());

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    • 1970-01-01
    • 1970-01-01
    • 2018-12-01
    • 1970-01-01
    相关资源
    最近更新 更多