-1

Suppose I had a two maps region1, region2 and both are declared as

LinkedHashMap<String, List<String>> region1 = new LinkedHashMap<>();

LinkedHashMap<String, List<String>> region2 = new LinkedHashMap<>();

region1 contains the below values:

region1 : {R1 = [A, B, C, D]}

region2 contains the below values:

region2 : {R2 = [G, A, D, B]}

Considering the values of region1 as base values, iterate over the values of region2 and the non duplicate values must be placed in another map with the key of region2 and non duplicate value of region2.

So the map region3 contains

region3 : {R2 = [G]}

And we iterate region3 over another map comparing for the matched values

map1 : {1 = [G, C]}

Since there is match in the value, we need to add a blank space in the matched value.

So the map1 contains values

map1 : {1=[  , C]}
Karthik
  • 145
  • 1
  • 2
  • 12

2 Answers2

1

Edit: optimized.
Stream only. The original objects are not modified.
A little bit long, however.

final Map<String, List<String>> region1 = new LinkedHashMap<>();
region1.put("R1", new ArrayList<>(Arrays.asList("A", "B", "C", "D")));

final Map<String, List<String>> region2 = new LinkedHashMap<>();
region2.put("R2", new ArrayList<>(Arrays.asList("A", "G", "C", "B")));
region2.put("R3", new ArrayList<>(Arrays.asList("A", "G", "C", "B")));

final Stream<Entry<String, List<String>>> entries =
        region1.values()
               .stream()
               .flatMap(values ->
                       region2.entrySet()
                              .stream()
                              .map(e -> {
                                  final List<String> value =
                                          e.getValue()
                                           .stream()
                                           .filter(v -> !values.contains(v))
                                           .collect(toList());
                                  return new SimpleEntry<>(e.getKey(), value);
                              })
               );

final Map<String, List<String>> result = entries.collect(toMap(Entry::getKey, Entry::getValue));

And that is why I like Streams. With type inference (Java 10+) it is even cleaner.

LppEdd
  • 20,274
  • 11
  • 84
  • 139
1

Without using streams, you can solve it this way:

public static void main(String[] args) {

    // setup the input and output maps
    LinkedHashMap<String, List<String>> region1 = new LinkedHashMap<>();
    LinkedHashMap<String, List<String>> region2 = new LinkedHashMap<>();
    LinkedHashMap<String, List<String>> region3 = new LinkedHashMap<>();
    region1.put("R1", asList("A", "B", "C", "D"));
    region2.put("R2", asList("G", "A", "D", "B"));

    // for each key in region2
    for(String key : region2.keySet()) {

        // make a copy of the values for that key
        List<String> values = new ArrayList<>(region2.get(key));

        // remove all the duplicates from each of the lists in region1
        for (List<String> baseValues : region1.values()) {
            values.removeAll(baseValues);
        }

        // if there are any remaining list values
        if (values.size() > 0) {
            // put them into region3
            region3.put(key, values);
        }
    }

    System.out.println(region3);
}
Jason
  • 11,744
  • 3
  • 42
  • 46