【问题标题】:How to use multiple streams and .map functions in java 8 with lambda expressions如何在带有 lambda 表达式的 java 8 中使用多个流和 .map 函数
【发布时间】:2018-03-22 13:23:23
【问题描述】:

我有一个List counties,其中仅包含唯一的县名,还有一个List txcArray,其中包含该城市的城市名称、县名称和人口。

我需要仅使用带有 lambda 表达式的 Java 8 和 Streams 从 txcArray 获取每个县的最大城市名称。

这是我目前的代码:

List<String> largest_city_name = 
    counties.stream() 
            .map(a -> txcArray.stream()
                              .filter(b ->  b.getCounty().equals(a))
                              .mapToInt(c -> c.getPopulation())
                              .max())
            .collect( Collectors.toList());

我正在尝试在 .max() 之后添加另一个 .map 语句以获取人口最多的 City 的名称,但我的新 lambda 表达式在 txcArray 流中不存在,它仅将其识别为 @987654328 @ 类型和 texasCitiesClass 类型。这就是我想要做的。

 List<String> largest_city_name = 
     counties.stream() 
             .map(a -> txcArray.stream()
                               .filter( b ->  b.getCounty().equals(a))
                               .mapToInt(c->c.getPopulation())
                               .max()
                               .map(d->d.getName()))
             .collect( Collectors.toList());

谁能告诉我我做错了什么?

【问题讨论】:

    标签: java lambda collections java-8 java-stream


    【解决方案1】:

    好吧,一旦将城市的mapStream变成IntStream,你就无法恢复与int值对应的城市名称。

    使用Streammax而不是转换为IntStream

    List<String> largest_city_name =
        counties.stream() 
                .map(a -> txcArray.stream()
                                  .filter(b ->  b.getCounty().equals(a))
                                  .max(Comparator.comparingInt(City::getPopulation))
                                  .get())
                .map(City::getName)
                .collect(Collectors.toList());
    

    这样map 操作将每个县映射到其人口最多的City。注意max返回Optional&lt;City&gt;,所以Optional为空(即某些县没有城市),get()会抛出异常。

    为了避免这个问题,你可以写:

    List<String> largest_city_name =
        counties.stream() 
                .map(a -> txcArray.stream()
                                  .filter(b ->  b.getCounty().equals(a))
                                  .max(Comparator.comparingInt(City::getPopulation))
                                  .map(City::getName)
                                  .orElse(""))
                .collect(Collectors.toList());
    

    这会将一个没有城市的县映射到一个空的String

    此代码假定txcArrayList&lt;City&gt;,其中City 是:

    类城市{ public String getName () {return nam;} public int getPopulation() {return pop;} 公共字符串 getCounty() {return cnt;} 字符串名称; 国际流行; 字符串cnt; 公共城市(字符串名称,int pop,字符串cnt){ this.nam = 名称; this.pop = 流行; 这个.cnt = cnt; } }

    countiesList&lt;String&gt;。如果我的假设不准确,您将不得不做出一些调整。

    现在,使用以下Lists 测试代码:

    List<String> counties=new ArrayList<> ();
    counties.add ("First");
    counties.add ("Second");
    counties.add ("Third");
    counties.add ("Fourth");
    List<City> txcArray = new ArrayList<> ();
    txcArray.add (new City("One",15000,"First"));
    txcArray.add (new City("Two",12000,"First"));
    txcArray.add (new City("Three",150000,"Second"));
    txcArray.add (new City("Four",14000,"Second"));
    txcArray.add (new City("Five",615000,"Third"));
    txcArray.add (new City("Six",25000,"Third"));
    

    产生这个输出List:

    [One, Three, Five, ]
    

    【讨论】:

    • 你是对的,我输入了错误的变量名,谢谢你帮助我完成它。
    【解决方案2】:

    您完全不需要counties 列表。只需直播txcArray 并按县分组:

    Collection<String> largestCityNames = txcArray.stream()
            .collect(Collectors.groupingBy(
                    City::getCounty,
                    Collectors.collectingAndThen(
                            Collectors.maxBy(City::getPopulation),
                            o -> o.get().getName())))
            .values();
    

    【讨论】:

    • 不错。我没想到。简单得多。 +1
    • 我想,本意是最大城市名称的列表与县列表的顺序相同。在这里,最好保留Map,而不是城市名称的无序集合……
    猜你喜欢
    • 2015-10-07
    • 1970-01-01
    • 1970-01-01
    • 2017-06-13
    • 1970-01-01
    • 2020-10-06
    • 2017-06-02
    • 2018-01-25
    • 1970-01-01
    相关资源
    最近更新 更多