简体   繁体   English

如何在带有lambda表达式的java 8中使用多个流和.map函数

[英]How to use multiple streams and .map functions in java 8 with lambda expressions

I have a List counties which contains unique county names only, and a List txcArray which contains a city name, county name and population for that city. 我有一个List counties ,它只包含唯一的县名,还有一个List txcArray ,其中包含该城市的城市名称,县名和人口。

I need to get the largest city name of each county from txcArray using only Java 8 with lambda expressions and Stream s. 我需要从txcArray获取每个县的最大城市名称,只使用带有lambda表达式和Stream s的Java 8。

Here is the code I have so far: 这是我到目前为止的代码:

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());

I am trying to add another .map statement after .max() to get the name of the City with the largest population but my new lambda expression does not exists from the stream of txcArray it only recognizes it as an int type and a texasCitiesClass type. 我试图在.max()之后添加另一个.map语句来获取具有最大总体数量的City的名称但是我的新lambda表达式不存在于txcArray流中它只将它识别为int类型和texasCitiesClass类型。 Here is what I am trying to do. 这是我想要做的。

 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());

Can someone tell me what I am doing wrong? 有人能告诉我我做错了什么吗?

You don't need the counties list altogether. 您根本不需要counties名单。 Just stream txcArray and group by county: 只需流txcArray并按县分组:

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

Well, once to map the Stream of cities into an IntStream , there's no way for you to recover the name of the city corresponding with the int value. 好吧,一旦将城市Stream mapIntStream ,就无法恢复与int值对应的城市名称。

Use Stream 's max instead of converting to IntStream : 使用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());

This way the map operation maps each county to its City with the highest population. 通过这种方式, map操作将每个县映射到人口最多的City Note that max returns an Optional<City> , so it the Optional is empty (ie some county has no cities), get() will throw an exception. 请注意, max返回一个Optional<City> ,因此Optional为空(即某些县没有城市), get()将抛出异常。

To avoid that issue, you can write: 要避免这个问题,您可以写:

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());

This will map a county having no cities into an empty String . 这会将没有城市的县映射为空String

This code assumes txcArray is a List<City> , where City is: 此代码假定txcArrayList<City> ,其中City为:

class City { public String getName () {return nam;} public int getPopulation() {return pop;} public String getCounty() {return cnt;} String nam; class City {public String getName(){return nam;} public int getPopulation(){return pop;} public String getCounty(){return cnt;} String nam; int pop; int pop; String cnt; String cnt; public City(String nam,int pop,String cnt) { this.nam = nam; public City(String nam,int pop,String cnt){this.nam = nam; this.pop = pop; this.pop = pop; this.cnt = cnt; this.cnt = cnt; } } }}

and counties is a List<String> . counties是一个List<String> If my assumptions are not accurate, you'll have to make some adjustments. 如果我的假设不准确,您将不得不做出一些调整。

Now, testing the code with the following List s: 现在,使用以下List测试代码:

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"));

produces this output List : 产生此输出List

[One, Three, Five, ]

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

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