Java 8流来收集项目列表的Map

时间:2018-04-17 21:44:54

标签: java java-8 java-stream

我有一张地图列表,用于存储角色和人名。例如:

List<Map<String, String>> listOfData

1) Role:  Batsman
   Name:  Player1

2)Role:  Batsman
   Name:  Player2

3)Role:  Bowler
   Name:  Player3

角色和名称是地图的键。 我想把它转换成Map<String, List<String>> result,它会给我一个每个角色的名单,即

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

这样做不会给我一个角色名称列表,它会给我一个名字。如何继续收集列表中的元素,然后将其添加到密钥?

用于创建基础结构的Java代码:

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

3 个答案:

答案 0 :(得分:5)

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

<强>更新

user1692342's完全相同的变体略有不同。

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

答案 1 :(得分:3)

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

答案 2 :(得分:0)

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