Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Merging two Map<String, Integer> with Java 8 Stream API

I have two (or more) Map<String, Integer> objects. I'd like to merge them with Java 8 Stream API in a way that values for common keys should be the maximum of the values.

@Test public void test14() throws Exception {     Map<String, Integer> m1 = ImmutableMap.of("a", 2, "b", 3);     Map<String, Integer> m2 = ImmutableMap.of("a", 3, "c", 4);     List<Map<String, Integer>> list = newArrayList(m1, m2);      Map<String, Integer> mx = list.stream()... // TODO      Map<String, Integer> expected = ImmutableMap.of("a", 3, "b", 3, "c", 4);     assertEquals(expected, mx); } 

How can I make this test method green?

I've played with collect and Collectors for a while without any success.

(ImmutableMap and newArrayList are from Google Guava.)

like image 759
user3528157 Avatar asked Apr 13 '14 03:04

user3528157


People also ask

How do I merge two maps together?

We can use putAll() method on any map instance and put all the entries from the given map into it. First, we created an empty output map and then added all the entries from both of the maps into it. As a result, we got merged entries from both of our maps.

How can I combine two HashMap objects containing the different types?

Assuming that both maps contain the same set of keys, and that you want to "combine" the values, the thing you would be looking for is a Pair class, see here for example. You simply iterate one of the maps; and retrieve values from both maps; and create a Pair; and push that in your result map.

What does the merge () method on map do?

Java HashMap merge() The Java HashMap merge() method inserts the specified key/value mapping to the hashmap if the specified key is already not present. If the specified key is already associated with a value, the method replaces the old value with the result of the specified function.

How do I merge two maps in groovy?

The easiest way to merge two maps in Groovy is to use + operator. This method is straightforward - it creates a new map from the left-hand-side and right-hand-side maps.

How to merge two maps in Java 8?

We will demonstrate merging two maps with different approaches. Java 8 adds a new merge () function into the java.util.Map interface. Learn and master in Java 8 features at Java 8 Tutorial with Examples.

How do you merge two streams into one map?

First, we transform map1 and map2 into a single stream. Next, we convert the stream into the map. As we can see, the last argument of toMap () is a merging function.

How does merge() function work in Java 8?

Java 8 adds a new merge () function into the java.util.Map interface. Here is how the merge () function works: If the specified key is not already associated with a value or the value is null, it associates the key with the given value. Otherwise, it replaces the value with the results of the given remapping function.

How to combine two Java 8 streams into one stream?

The Stream API in Java 8 can also provide an easy solution to our problem. First, we need to combine our Map instances into one Stream. That's exactly what Stream.concat () operation does: Stream combined = Stream.concat (map1.entrySet ().stream (), map2.entrySet ().stream ());


1 Answers

@Test public void test14() throws Exception {     Map<String, Integer> m1 = ImmutableMap.of("a", 2, "b", 3);     Map<String, Integer> m2 = ImmutableMap.of("a", 3, "c", 4);      Map<String, Integer> mx = Stream.of(m1, m2)         .map(Map::entrySet)          // converts each map into an entry set         .flatMap(Collection::stream) // converts each set into an entry stream, then                                      // "concatenates" it in place of the original set         .collect(             Collectors.toMap(        // collects into a map                 Map.Entry::getKey,   // where each entry is based                 Map.Entry::getValue, // on the entries in the stream                 Integer::max         // such that if a value already exist for                                      // a given key, the max of the old                                      // and new value is taken             )         )     ;      /* Use the following if you want to create the map with parallel streams     Map<String, Integer> mx = Stream.of(m1, m2)         .parallel()         .map(Map::entrySet)          // converts each map into an entry set         .flatMap(Collection::stream) // converts each set into an entry stream, then                                      // "concatenates" it in place of the original set         .collect(             Collectors.toConcurrentMap(        // collects into a map                 Map.Entry::getKey,   // where each entry is based                 Map.Entry::getValue, // on the entries in the stream                 Integer::max         // such that if a value already exist for                                      // a given key, the max of the old                                      // and new value is taken             )         )     ;     */      Map<String, Integer> expected = ImmutableMap.of("a", 3, "b", 3, "c", 4);     assertEquals(expected, mx); } 
like image 135
srborlongan Avatar answered Sep 22 '22 08:09

srborlongan