diff --git a/core-java-modules/core-java-streams-maps/src/test/java/com/baeldung/streams/mapstreamtomap/MapStreamToMapUnitTest.java b/core-java-modules/core-java-streams-maps/src/test/java/com/baeldung/streams/mapstreamtomap/MapStreamToMapUnitTest.java new file mode 100644 index 0000000000..b23dd07fc8 --- /dev/null +++ b/core-java-modules/core-java-streams-maps/src/test/java/com/baeldung/streams/mapstreamtomap/MapStreamToMapUnitTest.java @@ -0,0 +1,143 @@ +package com.baeldung.streams.mapstreamtomap; + +import static java.lang.Math.max; +import static java.util.stream.Collectors.flatMapping; +import static java.util.stream.Collectors.groupingBy; +import static java.util.stream.Collectors.mapping; +import static java.util.stream.Collectors.reducing; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; + +import java.util.HashMap; +import java.util.Map; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +import org.junit.jupiter.api.Test; + +public class MapStreamToMapUnitTest { + + Map playerMap1 = new HashMap() {{ + put("Kai", 92); + put("Liam", 100); + }}; + Map playerMap2 = new HashMap() {{ + put("Eric", 42); + put("Kevin", 77); + }}; + Map playerMap3 = new HashMap() {{ + put("Saajan", 35); + }}; + Map playerMap4 = new HashMap() {{ + put("Kai", 76); + }}; + Map playerMap5 = new HashMap() {{ + put("Kai", null); + put("Jerry", null); + }}; + + @Test + void givenMapsStream_whenUsingFlatMapAndToMap_thenMultipleMapsMergedIntoOneMap() { + + Map expectedMap = new HashMap() {{ + put("Saajan", 35); + put("Liam", 100); + put("Kai", 92); + put("Eric", 42); + put("Kevin", 77); + }}; + + Map mergedMap = Stream.of(playerMap1, playerMap2, playerMap3) + .flatMap(map -> map.entrySet() + .stream()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)); + + assertEquals(expectedMap, mergedMap); + } + + @Test + void givenMapsWithDuplicateKeys_whenUsingFlatMapAndToMap_thenMultipleMapsMergedIntoOneMap() { + + Map expectedMap = new HashMap() {{ + put("Saajan", 35); + put("Liam", 100); + put("Kai", 92); // max of 76 and 92 + put("Eric", 42); + put("Kevin", 77); + }}; + + assertThrows(IllegalStateException.class, () -> Stream.of(playerMap1, playerMap2, playerMap3, playerMap4) + .flatMap(map -> map.entrySet() + .stream()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)), "Duplicate key Kai (attempted merging values 92 and 76)"); + + Map mergedMap = Stream.of(playerMap1, playerMap2, playerMap3, playerMap4) + .flatMap(map -> map.entrySet() + .stream()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Integer::max)); + + assertEquals(expectedMap, mergedMap); + } + + private Integer maxInteger(Integer int1, Integer int2) { + if (int1 == null) { + return int2; + } + if (int2 == null) { + return int1; + } + return max(int1, int2); + } + + @Test + void givenMapsWithDuplicateKeysAndNullValues_whenUsingFlatMapWithForEach_thenMultipleMapsMergedIntoOneMap() { + + Map expectedMap = new HashMap() {{ + put("Saajan", 35); + put("Liam", 100); + put("Kai", 92); // max of 92, 76, and null + put("Eric", 42); + put("Kevin", 77); + put("Jerry", null); + }}; + + assertThrows(NullPointerException.class, () -> Stream.of(playerMap1, playerMap2, playerMap3, playerMap4, playerMap5) + .flatMap(map -> map.entrySet() + .stream()) + .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, Integer::max))); + + Map mergedMap = new HashMap<>(); + Stream.of(playerMap1, playerMap2, playerMap3, playerMap4, playerMap5) + .flatMap(map -> map.entrySet() + .stream()) + .forEach(entry -> { + String k = entry.getKey(); + Integer v = entry.getValue(); + if (mergedMap.containsKey(k)) { + mergedMap.put(k, maxInteger(mergedMap.get(k), v)); + } else { + mergedMap.put(k, v); + } + }); + assertEquals(expectedMap, mergedMap); + + } + + @Test + void givenMapsWithDuplicateKeysAndNullValues_whenUsingReduce_thenMultipleMapsMergedIntoOneMap() { + + Map expectedMap = new HashMap() {{ + put("Saajan", 35); + put("Liam", 100); + put("Kai", 92); // max of 92, 76, and null + put("Eric", 42); + put("Kevin", 77); + put("Jerry", null); + }}; + Map mergedMap = Stream.of(playerMap1, playerMap2, playerMap3, playerMap4, playerMap5) + .flatMap(x -> x.entrySet() + .stream()) + .collect(groupingBy(Map.Entry::getKey, mapping(Map.Entry::getValue, reducing(null, this::maxInteger)))); + assertEquals(expectedMap, mergedMap); + } +} \ No newline at end of file