-1

I am learning the Java language and found this exercise. I understood that they wanted to concatenate the list of hashmap into one hashmap in the same order and without overwriting the key, but I did not understand the examples so I do not find an arrangement in them as they say so I think my understanding was wrong. Can you explain to me how they are working?

Concatenate Map

This function will be given a single parameter known as the Map List. The Map List is a list of maps. Your job is to combine all the maps found in the map list into a single map and return it. There are two rules for adding values to the map.

You must add key-value pairs to the map in the same order they are found in the Map List. If the key already exists, it cannot be overwritten. In other words, if two or more maps have the same key, the key to be added cannot be overwritten by the subsequent maps.
Signature:

public static HashMap<String, Integer> concatenateMap(ArrayList<HashMap<String, Integer>> mapList)

Example:

INPUT: [{b=55, t=20, f=26, n=87, o=93}, {s=95, f=9, n=11, o=71}, {f=89, n=82, o=29}]
OUTPUT: {b=55, s=95, t=20, f=26, n=87, o=93}
INPUT: [{v=2, f=80, z=43, k=90, n=43}, {d=41, f=98, y=39, n=83}, {d=12, v=61, y=44, n=30}]
OUTPUT: {d=41, v=2, f=80, y=39, z=43, k=90, n=43}
INPUT: [{p=79, b=10, g=28, h=21, z=62}, {p=5, g=87, h=38}, {p=29, g=44, x=59, y=8, z=82}]
OUTPUT: {p=79, b=10, g=28, h=21, x=59, y=8, z=62}
Nick is tired
  • 6,860
  • 20
  • 39
  • 51
lasseg
  • 11
  • 5
  • Seems straightforward. What have you tried? Could you please share your code i.e. what you've tried? – Kamal Kunjapur Jun 23 '20 at 11:22
  • This task is only hard to understand because out entries are in weird order. You basicly need to add all pairs as you get them by iterating in order the list and check whether or not they already exist in the output map. – Amongalen Jun 23 '20 at 11:27
  • I've just add a Stream solution, if you could just take a look :) – azro Jun 28 '20 at 21:05

5 Answers5

0
public static void main(String[] args) {

    //{b=55, t=20, f=26, n=87, o=93}, {s=95, f=9, n=11, o=71}, {f=89, n=82, o=29}
    HashMap<String, Integer> map1 = new HashMap<>();
    map1.put("b", 55);
    map1.put("t", 20);
    map1.put("f", 26);
    map1.put("n", 87);
    map1.put("o", 93);

    HashMap<String, Integer> map2 = new HashMap<>();
    map2.put("s", 95);
    map2.put("f", 9);
    map2.put("n", 11);
    map2.put("o", 71);

    HashMap<String, Integer> map3 = new HashMap<>();
    map3.put("f", 89);
    map3.put("n", 82);
    map3.put("o", 29);

    ArrayList<HashMap<String, Integer>> list = new ArrayList<>();
    list.add(map1);
    list.add(map2);
    list.add(map3);

    HashMap<String, Integer> flat = concatenateMap(list);

    System.out.println(flat.toString());

}

public static HashMap<String, Integer> concatenateMap(ArrayList<HashMap<String, Integer>> mapList){

    HashMap<String, Integer> result = new HashMap<>();

    //iterate all maps
    for(HashMap<String, Integer> map : mapList){

        //iterate all keys from map
        for(String key : map.keySet()){

            //if result already contains key, skip
            if(result.containsKey(key)){
                continue;
            }

            result.put(key, map.get(key));

        }

    }

    return result;

}
KunLun
  • 3,109
  • 3
  • 18
  • 65
0

Try this.

public static Map<String, Integer> concatenateMap(List<Map<String, Integer>> list) {
    Map<String, Integer> result = new HashMap<>();
    for (Map<String, Integer> map : list)
        for (Entry<String, Integer> e : map.entrySet())
            result.computeIfAbsent(e.getKey(), k -> e.getValue());
    return result;
}

and test:

Map<String, Integer> actual = concatenateMap(List.of(
    Map.of("b", 55, "t", 20, "f", 26, "n", 87, "o", 93),
    Map.of("s", 95, "f", 9, "n", 11, "o", 71),
    Map.of("f", 89, "n", 82, "o", 29)));
Map<String, Integer> expected =
    Map.of("b", 55, "s", 95, "t", 20, "f", 26, "n", 87, "o", 93);
System.out.println(actual.equals(expected) ? "OK" : "NG");
// -> OK
0

If you are using Java 8 or above:

public static HashMap<String, Integer> concatenateMap(ArrayList<HashMap<String, Integer>> mapList){

    HashMap<String, Integer> result = new HashMap<>();
    mapList.stream().flatMap(map -> map.entrySet().stream()).forEachOrdered(m -> {
        result.putIfAbsent(m.getKey(), m.getValue());
    });
    return result;
}
Manoj
  • 21
  • 2
0

First of all, please read How HashMap really works? There are also two more references in this question which explains HashMap more detailed.

In addition to HashMap, in your problem you have ArrayList in which there are HashMaps. So there are HaspMaps with values as below (to add values to HashMap there is method put(Key, Value)):

    HashMap<String, Integer> map1 = new HashMap<>();
    map1.put("b", 55);
    map1.put("t", 20);
    map1.put("f", 26);
    map1.put("n", 87);
    map1.put("o", 93);

    HashMap<String, Integer> map2 = new HashMap<>();
    map2.put("s", 95);
    map2.put("f", 9);
    map2.put("n", 11);
    map2.put("o", 71);

    HashMap<String, Integer> map3 = new HashMap<>();
    map3.put("f", 89);
    map3.put("n", 82);
    map3.put("o", 29);

And all those HashMaps are stored in ArrayList as below:

    ArrayList<HashMap<String, Integer>> list = new ArrayList<>();
    list.add(map1);
    list.add(map2);
    list.add(map3);

In your question it is written that:

This function will be given a single parameter known as the Map List

So list object is the above-mentioned single parameter. Now we will pass to this parameter to a function which concatenates all maps (without overridden any existing key) and returns one HashMap. Here is the function:

    public static HashMap<String, Integer> concatenateMap(ArrayList<HashMap<String, Integer>> mapList){
        HashMap<String, Integer> map = mapList.get(0);

        for (int i = 1; i < mapList.size(); ++i) {
            for (Map.Entry<String, Integer> m : mapList.get(i).entrySet()) {
                if (!map.containsKey(m.getKey())) map.put(m.getKey(), m.getValue());
            }
        }

        return map;
    }

So in this function a map is created and first element of list directly assign on it, in this way we can skip first iteration, because keys are unique in each HashMap and anyway all elements of first HashMap will be added in map. After that we start from second element (int i = 1), and we iterate each HashMap. Also we have inner loop in which we iterate elements of each HashMap (Key, Value pairs). Lastly we check each key's existence in our map object, if it is already in map, we skip it not to override, otherwise we add it. After loops, we return our map object.

Sercan
  • 2,081
  • 2
  • 10
  • 23
0

Using Stream that is pretty easy, the third param (i1, i2) -> i1) allows to choose first value in case of key duplicate

static Map<String, Integer> concatenateMap(List<Map<String, Integer>> mapList) {
    return mapList.stream().map(Map::entrySet).flatMap(Set::stream)
                  .collect(Collectors.toMap(Entry::getKey, Entry::getValue, (i1, i2) -> i1));
}
azro
  • 53,056
  • 7
  • 34
  • 70