合并具有重复键的地图列表[重复]

问题描述 投票:0回答:4

我有一个

HashMap<Integer, ArrayList<String>>
列表,想将它们合并到循环中。 问题是每个地图的键都从 0 开始,因此键会重复。
putAll()
不起作用,因为它会覆盖按键并始终为我提供最后一张地图。

我见过使用 Stream 合并两个地图的示例,但就我而言,可能有超过 2 个地图。我正在尝试生成一个具有增量密钥的合并地图。例如:

假设我的列表中有 2 个地图(可能更多),并且两个键都从 0 开始,但以不同的值结束。

第一个地图,钥匙从 0 开始,到 10 结束

第二张地图,钥匙从 0 开始,到 15 结束

是否可以添加密钥从11开始的第二张地图? 最后,我需要一个合并的映射,其中第一个键从 0 开始,最后一个键以 25 结束。

java dictionary merge collections java-stream
4个回答
2
投票

假设您有一个地图列表,其中每个地图的键都是

[0-k], [0-n], [0, r] ...
范围内的整数,并且您生成的地图应该在
[0 - (k+n+r..)]
范围内设置一个键,如下所示应该可以工作:

public static void main(String[] args) throws IOException {
   //example list of maps
   List<Map<Integer,List<String>>> mapList = List.of(
           Map.of( 0,List.of("foo","foo"), 
                   1,List.of("bar","bar"), 
                   2,List.of("baz","baz")),
           Map.of( 0,List.of("doo","doo"), 
                   1,List.of("gee","gee"), 
                   2,List.of("woo","woo")),
           Map.of( 0,List.of("cab","cab"), 
                   1,List.of("kii","kii"), 
                   2,List.of("taa","taa"))
   );
   AtomicInteger ai = new AtomicInteger();
   Map<Integer,List<String>> result = 
           mapList.stream()
                   .flatMap(map -> map.values().stream())
                   .collect(Collectors.toMap(list -> ai.getAndIncrement(), Function.identity()));
   result.forEach((k,v) ->{
       System.out.println(k + " : " + v);
   });
}

2
投票

我会迭代您拥有的任意数量的地图,然后对于您想要组合的每个地图,迭代条目。对于每个条目,您可以使用

computeIfAbsent
有条件地为键创建一个空列表,然后对值调用
addAll
。例如:

List<Map<Integer, List<String>>> maps = List.of(
        Map.of(1, List.of("hello")),
        Map.of(2, List.of("world")),
        Map.of(1, List.of("a"), 2, List.of("b"))
);

Map<Integer, List<String>> combined = new HashMap<>();
for (Map<Integer, List<String>> map : maps) {
    for (Map.Entry<Integer, List<String>> e : map.entrySet()) {
        combined.computeIfAbsent(e.getKey(), k -> new ArrayList<>()).addAll(e.getValue());
    }
}

0
投票

如果您更喜欢流方法

Map<Integer, List<String>> m1;
Map<Integer, List<String>> m2;
Map<Integer, List<String>> m3;

Map<Integer, List<String>> combined = new HashMap<>();
Stream
    .of(m1, m2, m3)
    .flatMap(m -> m.entrySet().stream())
    .forEach(e -> combined.computeIfAbsent(e.getKey(), k -> new ArrayList<>())
            .addAll(e.getValue()));

0
投票

我知道你要求一张地图,但根据你对最终解决方案的解释以及你的键现在是从 0 开始的连续整数的事实,你可以只创建一个

List<List<String>>
。 在这种情况下,你可以这样做:

List<List<String>> result = mapList.stream()
               .flatMap(map->map.values().stream())
               .collect(Collectors.toList());                      

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.