merge two Map Values in Java and if key is same append the Values not overwrite in Java 7 or Java 8

huangapple go评论86阅读模式
英文:

merge two Map Values in Java and if key is same append the Values not overwrite in Java 7 or Java 8

问题

我想要合并两个 Map,但当键相同时,值应该被追加而不是被覆盖。

假设有

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]}

如果有人可以帮助我解决,将不胜感激。

英文:

I want to merge 2 Maps, but when the key is the same, the values should be appended instead of overwritten.

Let's say

Map&lt;String, Set&lt;String&gt;&gt; map1 = new HashMap&lt;&gt;();
Set&lt;String&gt; set1 = new HashSet&lt;&gt;();
set1.add(&quot;AB&quot;);
set1.add(&quot;BC&quot;);
map1.put(&quot;ABCD&quot;,set1);

Map&lt;String, Set&lt;String&gt;&gt; map2 = new HashMap&lt;&gt;();
Set&lt;String&gt; set2 =new HashSet&lt;&gt;();
set2.add(&quot;CD&quot;);
set2.add(&quot;EF&quot;);
map2.put(&quot;ABCD&quot;,set2);

map1.putAll(map2);

So here the key is same.I know putAll will overwrite the values if key is same

But I am looking for an output like

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

If someone can help me to resolve, will be so thankful.

答案1

得分: 5

你可以使用 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]}

英文:

You can concat two maps using Stream.concat then collect using groupingBy map key and value as Set.

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

Note: Solution use Java 9+ flatMapping

Or

You can use merge function of map. Here merge map2 data into map1

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

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

答案2

得分: 3

You make use of the merging function provided to Collectors.toMap that specifies what to do with values of duplicate keys with Streams.

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

You can apply a similar approach using Map#merge.

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())));
英文:

You make use of the merging function provided to Collectors.toMap that specifies what to do with values of duplicate keys with Streams. <sup>Demo</sup>

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

You can apply a similar approach using Map#merge. <sup>Demo</sup>

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

答案3

得分: 1

// 使用 **Stream API** 合并相同键的值,检查 `map2` 是否具有来自 `map1` 的相同键,然后遍历这些键并使用 `addAll()` 合并值

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

---

// 输出

{ABCD=[AB, BC, CD, EF]}
英文:

You can use Stream API to merge the values of the same keys, Check if the map2 has the same keys from map1 and loop over them and merge the values together using addAll()

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

, main function

public static void main(String[] args) {
    Map&lt;String, Set&lt;String&gt;&gt; map1 = new HashMap&lt;&gt;();
    Set&lt;String&gt; set1 = new HashSet&lt;&gt;();
    set1.add(&quot;AB&quot;);
    set1.add(&quot;BC&quot;);
    map1.put(&quot;ABCD&quot;, set1);

    Map&lt;String, Set&lt;String&gt;&gt; map2 = new HashMap&lt;&gt;();
    Set&lt;String&gt; set2 = new HashSet&lt;&gt;();
    set2.add(&quot;CD&quot;);
    set2.add(&quot;EF&quot;);
    map2.put(&quot;ABCD&quot;, set2);

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

    System.out.println(map1);
}

, output

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

huangapple
  • 本文由 发表于 2020年7月26日 03:47:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/63092862.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定