Java 8 stream to collect a Map of List of items

[亡魂溺海] 提交于 2021-01-26 18:10:23

问题


I have a List of Maps which stores the roles and the names of people. For ex:

List<Map<String, String>> listOfData

1) Role:  Batsman
   Name:  Player1

2)Role:  Batsman
   Name:  Player2

3)Role:  Bowler
   Name:  Player3

Role and Name are the Keys of the map. I want to convert this into a Map<String, List<String>> result, which will give me a list of names for each role, i.e

k1: Batsman  v1: [Player1, Player2]
k2: Bowler   v2: [Player3]


listOfData
    .stream()
    .map(entry -> new AbstractMap.SimpleEntry<>(entry.get("Role"), entry.get("Name"))
    .collect(Collectors.toList());

Doing this way will not give me a list of names for the role, it will give me a single name. How do i keep collecting the elements of the list and then add it to a key ?

Java code to create base structure:

Map<String, String> x1 = ImmutableMap.of("Role", "Batsman", "Name", "Player1");

        Map<String, String> y1 = ImmutableMap.of("Role", "Batsman", "Name", "Player2");

        Map<String, String> z1 = ImmutableMap.of("Role", "Bowler", "Name", "Player3");


        List<Map<String, String>> list = ImmutableList.of(x1, y1, z1);
        Map<String, List<String>> z = list.stream()
                    .flatMap(e -> e.entrySet().stream())
                    .collect(Collectors.groupingBy(Map.Entry::getKey,
                            Collectors.mapping(Map.Entry::getValue, Collectors.toList())));

回答1:


listOfData.stream()
          .flatMap(e -> e.entrySet().stream())
          .collect(Collectors.groupingBy(Map.Entry::getKey, 
                         Collectors.mapping(Map.Entry::getValue, 
                                    Collectors.toList())));

update:

Slightly different variant to user1692342's answer for completeness.

list.stream()
    .map(e -> Arrays.asList(e.get("Role"), e.get("Name")))
    .collect(Collectors.groupingBy(e -> e.get(0),
             Collectors.mapping(e -> e.get(1), Collectors.toList())));



回答2:


Based on the idea given by Aomine:

list.stream()
    .map(e -> new AbstractMap.SimpleEntry<>(e.get("Role"), e.get("Name")))
    .collect(Collectors.groupingBy(Map.Entry::getKey,
                    Collectors.mapping(Map.Entry::getValue, Collectors.toList())));



回答3:


    Map<String, List<Person>> groupByPriceMap = lis.stream().collect(Collectors.groupingBy(Person::getRole));


来源:https://stackoverflow.com/questions/49887953/java-8-stream-to-collect-a-map-of-list-of-items

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!