简体   繁体   English

列表列表的列表到 map 的展平 map 的列表

[英]List of lists of lists to a map of flatten map of lists

I have a lists(states) of lists(cities) of lists(towns).我有列表(城镇)列表(城市)的列表(州)。 How do I flatten the middle list(cities) and convert to a map(state's name) of map(town's name) of lists(towns)?如何展平中间列表(城市)并转换为列表(城镇)的地图(城镇名称)的地图(州名)?

This question may look similar to the other question Java 3 level nested list to 3 level nested map , but they are not the same.这个问题可能看起来类似于另一个问题Java 3 级嵌套列表到 3 级嵌套 map ,但它们并不相同。 This one, I need to flatten one of the lists.这一个,我需要展平其中一个列表。

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Data
@AllArgsConstructor
class Country {
    private String name;
    private List<State> states;
}

@Data
@AllArgsConstructor
class State {
    private String name;
    private List<City> cities;
}

@Data
@AllArgsConstructor
class City {
    private String name;
    private List<Town> towns;
}

@Data
@AllArgsConstructor
class Town {
    private String name;
    private String address;
    private Integer population;
}

public static void main(String[]args) {
    List<Town> countryAStateACityATownsList = new ArrayList();
    countryAStateACityATownsList.add(new Town("CountryA-StateA-CityA-TownA", "addressOfCountryA-StateA-CityA-TownA", 100));
    countryAStateACityATownsList.add(new Town("CountryA-StateA-CityA-TownB", "addressOfCountryA-StateA-CityA-TownB", 100));
    countryAStateACityATownsList.add(new Town("CountryA-StateA-CityA-TownC", "addressOfCountryA-StateA-CityA-TownC", 100));

    List<Town> countryAStateACityBTownsList = new ArrayList();
    countryAStateACityBTownsList.add(new Town("CountryA-StateA-CityB-TownA", "addressOfCountryA-StateA-CityB-TownA", 100));
    countryAStateACityBTownsList.add(new Town("CountryA-StateA-CityB-TownB", "addressOfCountryA-StateA-CityB-TownB", 100));
    countryAStateACityBTownsList.add(new Town("CountryA-StateA-CityB-TownC", "addressOfCountryA-StateA-CityB-TownC", 100));

    List<Town> countryAStateACityCTownsList = new ArrayList();
    countryAStateACityCTownsList.add(new Town("CountryA-StateA-CityC-TownA", "addressOfCountryA-StateA-CityC-TownA", 100));
    countryAStateACityCTownsList.add(new Town("CountryA-StateA-CityC-TownB", "addressOfCountryA-StateA-CityC-TownB", 100));
    countryAStateACityCTownsList.add(new Town("CountryA-StateA-CityC-TownC", "addressOfCountryA-StateA-CityC-TownC", 100));

    City cityA = new City("cityA", countryAStateACityATownsList);
    City cityB = new City("cityB", countryAStateACityBTownsList);
    City cityC = new City("cityC", countryAStateACityCTownsList);

    List<City> countryAStateACitiesList = new ArrayList<>();
    countryAStateACitiesList.add(cityA);
    countryAStateACitiesList.add(cityB);
    countryAStateACitiesList.add(cityC);

        State stateA = new State("stateA",countryAStateACitiesList);

        Country countryA = new Country("countryA", Collections.singletonList(stateA));
   
    }

}

I want a map of states of towns.我想要一个城镇州的 map。 (so city list is flatten): state.name -> town.name -> town. (所以城市列表是扁平的):state.name -> town.name -> town。 I want to do something like destinationMap.get("stateA").get("CountryA-StateA-CityA-TownA") and that would give me the town instance that has the name "CountryA-StateA-CityA-TownA".我想做一些类似destinationMap.get("stateA").get("CountryA-StateA-CityA-TownA") 的事情,这会给我一个名为“CountryA-StateA-CityA-TownA”的城镇实例。

Please help, I have been trying to accomplish this by using stream, but not able to so far.请帮忙,我一直在尝试通过使用 stream 来实现这一点,但到目前为止还不能。

I have tried this:我试过这个:

        countryA.getStates()
               .stream()
               .collect(Collectors.toMap(State::getName,
                        st-> st.getCities()
                               .stream()
                               .collect(Collectors.toMap(City::getName,
                                                         City::getTowns))));

This creates a map of state.name to city.name to towns.这将创建 state.name 到 city.name 到城镇的 map。 But this is not what I want.但这不是我想要的。 在此处输入图像描述

I want a map of state.name to town.name to the town that has the same name.我想要一个 state.name 的 map 到 town.name 到同名的城镇。

I love functional parts of Java, here's what I did, seems to work the way you wanted to retrieve towns.我喜欢 Java 的功能部件,这就是我所做的,似乎按照您想要检索城镇的方式工作。

Map<String, Map<String, Town>> map =
  countryA.getStates()
    .stream()
    .collect(Collectors.toMap(State::getName,
      st -> st.getCities()
        .stream()
        .map(City::getTowns)
        .flatMap(List::stream)
        .collect(Collectors.toMap(Town::getName, Function.identity()))));
System.out.println(map.get("stateA").get("CountryA-StateA-CityA-TownA"));

Gives output赠送 output

Town{name='CountryA-StateA-CityA-TownA', address='addressOfCountryA-StateA-CityA-TownA', population=100}

And watch out, you have duplicates in your example, I assumed there should not be duplicates of towns in different cities.请注意,您的示例中有重复项,我认为不同城市的城镇不应重复。 Let me know if this is what you wanted!让我知道这是否是您想要的!

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

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