【问题标题】:merge two Map Values in Java and if key is same append the Values not overwrite in Java 7 or Java 8 [duplicate]在 Java 中合并两个 Map 值,如果键相同,则附加在 Java 7 或 Java 8 中未覆盖的值 [重复]
【发布时间】:2020-11-15 11:00:04
【问题描述】:

我想合并2个Maps,但是当key相同时,应该追加而不是覆盖值。

我们说

Map<String, Set<String>> map1 = new HashMap<>();
Set<String> set1 = new HashSet<>();
set1.add("AB");
set1.add("BC");
map1.put("ABCD",set1);

Map<String, Set<String>> map2 = new HashMap<>();
Set<String> set2 =new HashSet<>();
set2.add("CD");
set2.add("EF");
map2.put("ABCD",set2);

map1.putAll(map2);

所以这里的键是相同的。我知道如果键相同,putAll 会覆盖值

但我正在寻找类似的输出

{ABCD=[AB,BC,CD,ED]}

如果有人能帮我解决,将不胜感激。

【问题讨论】:

  • 您想修改其中一张地图,还是创建全新的地图?

标签: java dictionary java-8 mergemap


【解决方案1】:

您可以使用Stream.concat 连接两个地图,然后使用groupingBy 地图键和值作为集合进行收集。

Map<String, Set<String>> res = 
       Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
             .collect(Collectors.groupingBy(e-> e.getKey(),
                                Collectors.flatMapping(e -> e.getValue().stream(), Collectors.toSet())));

注意: 解决方案使用 Java 9+ flatMapping

或者

您可以使用地图的merge 功能。这里合并map2数据到map1

map2.forEach((key, val) -> map1.merge(key, val, (a, b) -> {a.addAll(b); return a;}));

输出:{ABCD=[AB, BC, CD, EF]}

【讨论】:

  • flatMapping 不过是 java-9。
  • @Eugene 是的,我确实错过了那部分
  • 不用担心,反正这是最好的,恕我直言。 1+
【解决方案2】:

您可以使用 Stream API 合并相同键的值,检查 map2 是否具有来自 map1 的相同键并循环它们并使用 @987654323 将值合并在一起@

map1.entrySet().stream().filter(entry -> map2.containsKey(entry.getKey()))
                .forEach(entry -> entry.getValue().addAll(map2.get(entry.getKey())));

main 函数

public static void main(String[] args) {
    Map<String, Set<String>> map1 = new HashMap<>();
    Set<String> set1 = new HashSet<>();
    set1.add("AB");
    set1.add("BC");
    map1.put("ABCD", set1);

    Map<String, Set<String>> map2 = new HashMap<>();
    Set<String> set2 = new HashSet<>();
    set2.add("CD");
    set2.add("EF");
    map2.put("ABCD", set2);

    map1.entrySet()
        .stream()
        .filter(entry -> map2.containsKey(entry.getKey()))
        .forEach(entry -> entry.getValue().addAll(map2.get(entry.getKey())));

    System.out.println(map1);
}

output

{ABCD=[AB, BC, CD, EF]}

【讨论】:

  • 对不起,我没有得到正确的输出 Map 1 -&gt; {fghjk=[AB, BC], ABCD=[AB, BC]} Map 2 -&gt; {CDDFF=[CD, AB], ABCD=[CD, AB]} ResultMap After Merge -&gt; {fghjk=[AB, BC, CD], ABCD=[AB, BC, CD]} 需要像这样的输出:- ResultMap After Merge -&gt; {fghjk=[AB, BC], ABCD=[AB, BC, CD], CDDFF=[CD, AB]}
【解决方案3】:

您使用提供给Collectors.toMap 的合并功能,该功能指定如何处理Streams 中重复键的值。 Demo

final Map<String, Set<String>> map3 = Stream.concat(map1.entrySet().stream(), map2.entrySet().stream())
        .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
                (a, b) -> Stream.concat(a.stream(), b.stream()).collect(Collectors.toSet())));

您可以使用Map#merge 应用类似的方法。 Demo

final Map<String, Set<String>> map3 = new HashMap<>(map1);
map2.forEach((key, val) -> map3.merge(key, val,
        (a, b) -> Stream.concat(a.stream(), b.stream()).collect(Collectors.toSet())));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-05-20
    • 1970-01-01
    • 2022-06-15
    • 2021-12-02
    • 1970-01-01
    • 1970-01-01
    • 2017-07-03
    • 2021-05-10
    相关资源
    最近更新 更多