-2

ArrayList<Map<String, String>> result1

result1 is like

(1, a)
(2, a)
(3, b)
(4, e)
(5, e)

ArrayList<Map<String, String>> result2

result2 is like

(1,android)
(2,ios)
(3,android)
(4,android)
(5,ios)

I want to merge the two maps to build a map like this one

(1, ( a, android))
(2, ( a, ios))
(3, ( b, android))
(4, (e, android))
(5, (e, ios))

How to make this happen?

Thomas Fritsch
  • 9,639
  • 33
  • 37
  • 49
DavidW
  • 33
  • 6

4 Answers4

0

For the requirement you have specified here, you can do it like this.

I'm iterating over the keys of the first map. And collecting values for each key from all the maps and putting them in a list. Then put the list to the resulting map.

import java.util.*;

public class MergeMaps
{
  public static void main(String[] args)
  {
    Map<String, String> map1 = new HashMap<>();
    map1.put("1", "a");
    map1.put("2", "a");
    map1.put("3", "b");
    map1.put("4", "e");
    map1.put("5", "e");

    Map<String, String> map2 = new HashMap<>();
    map2.put("1", "android");
    map2.put("2", "ios");
    map2.put("3", "android");
    map2.put("4", "android");
    map2.put("5", "ios");

    Set<String> keys = new HashSet<>();
    keys.addAll(map1.keySet());
    keys.addAll(map2.keySet());

    Map<String, List<String>> mergedMap = new HashMap<>();
    for (String key : keys)
    {
      List<String> list = new ArrayList<>();
      list.add(map1.get(key));
      list.add(map2.get(key));
      mergedMap.put(key, list);
    }

    System.out.println(mergedMap);
  }
}

Output will be:

{1=[a, android], 2=[a, ios], 3=[b, android], 4=[e, android], 5=[e, ios]}

Prasad Karunagoda
  • 2,048
  • 2
  • 12
  • 16
0

You can merge two streams with Stream.concat() and group them with Collectors.groupingBy() and Collectors.mapping():

Map<String, String> first = Map.of("1", "a", "2", "a");
Map<String, String> second = Map.of("1", "android", "2", "ios");
Map<String, List<String>> result = Stream.concat(first.entrySet().stream(), second.entrySet().stream())
            .collect(groupingBy(Entry::getKey, mapping(Entry::getValue, toList())));
System.out.println(result);

will output:

{1=[a, android], 2=[a, ios]}
Karol Dowbecki
  • 43,645
  • 9
  • 78
  • 111
0

You can try this approach as well:

Map<String, String> result1 = new HashMap<>();
// initialize result1 ...

Map<String, String> result2 = new HashMap<>();
// initialize result2 ...

Map<String, Map<String, String>> mergedResult = new HashMap<>();

Up to Java 8

result1.forEach((k1, v1) ->
            mergedResult.put(k1, new HashMap<String, String>() {{
                put(v1, result2.get(k1));
            }}));

Java 9 or later

result1.forEach((k1, v1) -> mergedResult.put(k1, 
                                 Map.of(v1, result2.get(k1))));
Saeed
  • 43
  • 1
  • 8
0

This is one way arriving at the result:

Input Data:

// The first list of data
List<Map<String, String>> list1 = new ArrayList<>();
list1.add(getMapData("1", "a"));
list1.add(getMapData("2", "a"));
list1.add(getMapData("3", "b"));
list1.add(getMapData("4", "e"));
list1.add(getMapData("5", "e"));
list1.add(getMapData("999", "x"));
System.out.println(list1);

Data 1: [{1=a}, {2=a}, {3=b}, {4=e}, {5=e}, {999=x}]

// The second list of data
List<Map<String, String>> list2 = new ArrayList<>();
list2.add(getMapData("1", "android"));
list2.add(getMapData("2", "ios"));
list2.add(getMapData("3", "android"));
list2.add(getMapData("4", "android"));
list2.add(getMapData("5", "ios"));
list2.add(getMapData("888", "zzzzz"));
System.out.println(list2);

Data 2: [{1=android}, {2=ios}, {3=android}, {4=android}, {5=ios}, {888=zzzzz}]

// utility method for creating test data
private static Map<String, String> getMapData(String k, String v) {
    Map<String, String> m = new HashMap<>();
    m.put(k, v);
    return m;
}


The Result Process:

The output is stored to a Map<String, List<String>>:

Map<String, List<String>> result = new HashMap<>();

// process the first list
for (Map<String, String> m : list1) {
    for (Map.Entry<String, String> entry : m.entrySet()) {
        List<String> valueList = new ArrayList<>();
        valueList.add(entry.getValue());
        result.put(entry.getKey(), valueList);
    }
}

// process the second list; merge with the first
for (Map<String, String> m : list2) {
    for (Map.Entry<String, String> entry : m.entrySet()) {
        String k = entry.getKey();
        List<String> valueList = result.get(k);
        if (valueList == null) {
            valueList = new ArrayList<>();
        }
        valueList.add(entry.getValue());
        result.put(k, valueList);
    }
}

System.out.println(result);

The Result:

{1=[a, android], 2=[a, ios], 3=[b, android], 4=[e, android], 5=[e, ios], 888=[zzzzz], 999=[x]}
prasad_
  • 12,755
  • 2
  • 24
  • 36