Merge below 3 maps if values exist then replace and if the value is new then add that value, for example :-
I have a Map1 as :-
{
BMW = {
SIZE=1,
SPEED=60
},
AUDI = {
SIZE=5,
SPEED=21
},
SEAT= {
SPEED=15
}
}
And a Map2 as :-
{
Suzuki = {
WHEELS_SIZE=2,
DOORS=3
},
AUDI = {
WHEELS_SIZE=5,
SIZE=4,
DOORS=5
},
SEAT= {
DOORS=4
}
}
And Map3 as :-
{
TOYOTA = {
WHEELS_SIZE=5,
DOORS=5
},
BMW= {
SIZE=10
}
}
I have a requirement to merge all 3 above so, that final map looks like
{
BMW = {
SIZE=10,
SPEED=60
},
AUDI = {
SIZE=4,
SPEED=21,
WHEELS_SIZE=5,
DOORS=5
},
SEAT= {
SPEED=15,
DOORS=4
},
Suzuki = {
WHEELS_SIZE=2,
DOORS=3
},
TOYOTA = {
WHEELS_SIZE=5,
DOORS=5
},
}
Could someone please suggest an optimized way to achieve this ? Thanks in advance!
CodePudding user response:
Here is a naïve implementation:
public static void main(String[] args){
Map<String, Integer> BMW1 = new HashMap<>();
BMW1.put("SIZE", 1);
BMW1.put("SPEED", 60);
Map<String, Integer> AUDI1 = new HashMap<>();
AUDI1.put("SIZE", 5);
AUDI1.put("SPEED", 21);
Map<String, Integer> SEAT1 = new HashMap<>();
SEAT1.put("SPEED", 15);
Map<String, Map<String, Integer>> one =
Map.of("BMW", BMW1, "AUDI", AUDI1, "SEAT", SEAT1);
Map<String, Integer> SUZUKI2 = new HashMap<>();
SUZUKI2.put("WHEEL_SIZE", 2);
SUZUKI2.put("DOORS", 3);
Map<String, Integer> AUDI2 = new HashMap<>();
AUDI2.put("WHEELS_SIZE", 5);
AUDI2.put("SIZE", 4);
AUDI2.put("DOORS", 5);
Map<String, Integer> SEAT2 = new HashMap<>();
SEAT2.put("DOORS", 4);
Map<String, Map<String, Integer>> two =
Map.of("SUZUKI", SUZUKI2, "AUDI", AUDI2, "SEAT", SEAT2);
Map<String, Integer> TOYOTA3 = new HashMap<>();
TOYOTA3.put("WHEEL_SIZE", 5);
TOYOTA3.put("DOORS", 5);
Map<String, Integer> BMW3 = new HashMap<>();
BMW3.put("SIZE", 10);
Map<String, Map<String, Integer>> three =
Map.of("TOYOTA", TOYOTA3, "BMW", BMW3);
Map<String, Map<String, Integer>>[] maps = new Map[]{ one, two, three };
Map<String, Map<String, Integer>> mergedMaps = mergeMaps(maps);
printMap(mergedMaps);
}
public static Map<String, Map<String, Integer>> mergeMaps(Map<String, Map<String, Integer>>[] maps) {
Map<String, Map<String, Integer>> mergedMap = new HashMap<>();
for(Map<String, Map<String, Integer>> map : maps) {
for(Map.Entry<String, Map<String, Integer>> entry : map.entrySet()) {
if(mergedMap.containsKey(entry.getKey())){
Map<String, Integer> mergedCarStats = mergedMap.get(entry.getKey());
Map<String, Integer> carStats = entry.getValue();
mergedCarStats.putAll(carStats);
} else {
mergedMap.put(entry.getKey(), entry.getValue());
}
}
}
return mergedMap;
}
public static void printMap(Map<String, Map<String, Integer>> car) {
System.out.println("{");
for(Map.Entry<String, Map<String, Integer>> entry: car.entrySet()) {
System.out.println(String.format(" %s = {", entry.getKey()));
printStats(entry.getValue());
System.out.println(" },");
}
System.out.println("}");
}
public static void printStats(Map<String, Integer> stats) {
for(Map.Entry<String, Integer> entry : stats.entrySet()) {
System.out.println(String.format(" '%s': %d,", entry.getKey(), entry.getValue()));
}
}
If you run it you will get this output:
{
SUZUKI = {
'WHEEL_SIZE': 2,
'DOORS': 3,
},
SEAT = {
'SPEED': 15,
'DOORS': 4,
},
AUDI = {
'SPEED': 21,
'DOORS': 5,
'SIZE': 4,
'WHEELS_SIZE': 5,
},
TOYOTA = {
'WHEEL_SIZE': 5,
'DOORS': 5,
},
BMW = {
'SPEED': 60,
'SIZE': 10,
},
}
Which is what you asked for. There are a few things to consider though. Using loops this way is inefficient because the time complexity is going to be O(n^2) as there are 2 for loops. There are built in functions for merging maps since Java 8 which could be worth exploring.
CodePudding user response:
Merge the three maps using java8
Map<String, Map<String, Integer>> resultMap = Stream.of(map1, map2, map3)
.flatMap(map -> map.entrySet().stream())
.collect(Collectors.toMap(
Map.Entry::getKey,
e -> new HashMap<String,Integer>(e.getValue()),
(key, value) -> {key.putAll(value); return key;}
));
Output:
{SEAT={SPEED=15, DOORS=4}, TOYOTA={WHEELS_SIZE=5, DOORS=5}, Suzuki={WHEELS_SIZE=2, DOORS=3}, AUDI={SPEED=21, WHEELS_SIZE=5, DOORS=5, SIZE=4}, BMW={SPEED=60, SIZE=10}}