从地图列表中创建地图

时间:2014-03-20 08:20:21

标签: java hashmap

我有一张地图清单。

List<Map<Integer, String>>

列表中的值例如是

<1, String1>
<2, String2>
<1, String3>
<2, String4>

作为最终结果,我想要一个Map&gt;,比如

<1, <String1, String3>>
<2, <String2, String4>>

我如何用Java实现这一目标。

代码:

List<Map<Integer, String>> genericList = new ArrayList<Map<Integer,String>>();
for(TrackActivity activity : activityMajor){
Map<Integer, String> mapIdResponse = activity.getMapIdResponse();
genericList.add(mapIdResponse);
}

现在这个genericList是输入,从这个列表中,基于我想要的相同ID

Map<Integer, List<String>> mapIdResponseList

基本上,要根据ID对String的响应进行分组,在列表中对响应进行分组,然后创建一个以id作为键,列表作为其值的新映射。

2 个答案:

答案 0 :(得分:14)

您可以使用Java 8执行以下操作:

private void init() {
    List<Map<Integer, String>> mapList = new ArrayList<>();

    Map<Integer, String> map1 = new HashMap<>();
    map1.put(1, "String1");
    mapList.add(map1);

    Map<Integer, String> map2 = new HashMap<>();
    map2.put(2, "String2");
    mapList.add(map2);

    Map<Integer, String> map3 = new HashMap<>();
    map3.put(1, "String3");
    mapList.add(map3);

    Map<Integer, String> map4 = new HashMap<>();
    map4.put(2, "String4");
    mapList.add(map4);

    Map<Integer, List<String>> response = mapList.stream()
            .flatMap(map -> map.entrySet().stream())
            .collect(
                    Collectors.groupingBy(
                            Map.Entry::getKey, 
                            Collectors.mapping(
                                    Map.Entry::getValue, 
                                    Collectors.toList()
                            )
                    )
            );
    response.forEach((i, l) -> {
        System.out.println("Integer: " + i + " / List: " + l);
    });
}

这将打印:

  

整数:1 /列表:[String1,String3]
  整数:2 /列表:[String2,String4]

解释(严重保证),我恐怕无法解释每一个细节,您需要先了解Java 8中引入的StreamCollectors API的基础知识:

  1. Stream<Map<Integer, String>>获取mapList
  2. 应用flatMap运算符,该运算符将流粗略地映射到已存在的流中 在这里:我将所有Map<Integer, String>转换为Stream<Map.Entry<Integer, String>>并将其添加到现有流中,因此现在它也是Stream<Map.Entry<Integer, String>>类型。
  3. 我打算将Stream<Map.Entry<Integer, String>>收集到Map<Integer, List<String>>
  4. 为此,我将使用Collectors.groupingBy,根据分组功能生成Map<K, List<V>>FunctionMap.Entry<Integer, String>映射到Integer在这种情况下。
  5. 为此,我使用方法参考,它完全符合我的要求,即Map.Entry::getKey,它在Map.Entry上运行并返回Integer
  6. 此时如果我没有做任何额外处理,我会得到Map<Integer, List<Map.Entry<Integer, String>>>
  7. 为了确保我获得正确的签名,我必须向Collectors.groupingBy添加下游,这必须提供收集器。
  8. 对于此下游,我使用收集器通过引用Map.EntryString条目映射到其Map.Entry::getValue值。
  9. 我还需要指定它们的收集方式,这里只是Collectors.toList(),因为我想将它们添加到列表中。
  10. 这就是我们获得Map<Integer, List,String>>的方式。

答案 1 :(得分:0)

看看guavas MultiMap。应该正是您所寻找的:

http://code.google.com/p/guava-libraries/wiki/NewCollectionTypesExplained#Multimap

相关问题