1. Overview

Map is a popular data structure commonly used in most Kotlin applications. By merging two maps, we can combine the key-value pairs from the two maps into a single one.

In this tutorial, we’ll explore multiple ways to merge two maps in Kotlin. Further, we’ll also see how each approach handles the scenario of conflicting elements, where the default behavior is to give preference to elements from the second map.

2. Using the Plus (+) Operator

First, let’s initialize two maps, map1 and map2, with mappings between string and integer values:

val map1 = mapOf("a" to 1, "b" to 2)
val map2 = mapOf("b" to 3, "c" to 4)

We must note that map1 and map2 are immutable, as we used mapOf() to initialize them.

Next, let’s use the + operator to merge map1 and map2 into a new map, mergedMap:

val mergedMap = map1 + map2

Lastly, let’s verify if we’ve got the correct results with our merge operation:

assertEquals(mapOf("a" to 1, "b" to 3, "c" to 4), mergedMap)

Great! We got the correct results.

3. Using the Plus Assign (+=) Operator

In scenarios with a mutable map, we can use the existing map to hold the results after merging the two maps.

Let’s start by defining one mutable map, map1, and an immutable map, map2:

val map1 = mutableMapOf("a" to 1, "b" to 2)
val map2 = mapOf("b" to 3, "c" to 4)

It’s important to note that we used mutableMapOf() to initialize the mutable map.

Now, we can use the += operator to merge the key-value pairs from the two maps into the mutable map, map1:

map1 += map2

In this case, we used the storage more efficiently by using an existing map.

Like earlier, we should verify the merge results in map1:

assertEquals(mapOf("a" to 1, "b" to 3, "c" to 4), map1)

Fantastic! We got this one right.

4. Using the putAll() Function

Alternatively, we can use the putAll() function to put all the key-value pairs from map2 into the mutable map, map1:

map1.putAll(map2)

Further, let’s verify the contents of the merged map, map1:

assertEquals(mapOf("a" to 1, "b" to 3, "c" to 4), map1)

We got the expected results.

5. Using the associateWith() Function

With the putAll() function, we get the default behavior where key-value pairs are merged as-is. However, we can define a custom behavior for merging by using the associateWith() function.

First, let’s define two immutable maps, map1 and map2:

val map1 = mapOf("a" to 1, "b" to 2)
val map2 = mapOf("b" to 3, "c" to 4)

Next, let’s use the associateWith() function to map each key with a value from map1 or map2:

val mergedMap = (map1.keys + map2.keys).associateWith {
  key -> map2[key] ?: map1[key]!!
}

We gave preference to map2, and if the key isn’t present in map2, then we used map1. Further, we used the !! operator to claim that we’re certain that key is present in map1 if it’s missing in map2.

Finally, we should verify that mergedMap contains the correct key-value pairs:

assertEquals(mapOf("a" to 1, "b" to 3, "c" to 4), mergedMap)

It looks like we nailed this one.

6. Using merge() From Java Map

Kotlin is 100% interoperable with Java. So, we can call methods from the Java classes directly.

First, let’s define a mutable map, map1, and an immutable map, map2, with a few sample key-value pairs:

val map1 = mutableMapOf("a" to 1, "b" to 2)
val map2 = mapOf("b" to 3, "c" to 4)

Now, let’s iterate over the key-value pairs from the immutable map, map2, and merge them into map1 using merge():

map2.forEach { (key, value) ->
  map1.merge(key, value) { oldVal, newVal -> newVal * oldVal}
}

It’s important to note that oldVal and newVal correspond to values from map1 and map2, respectively. Further, the merit of merge() over the put() method in Map is the flexibility of providing a remapping function. In this case, for each conflicting element, we multiply the values from the original maps to get the value for the merged map.

Lastly, we should validate our approach by checking the key-value pairs from map1:

assertEquals(mapOf("a" to 1, "b" to 6, "c" to 4), map1)

As expected, all key-value pairs from map2 and map1 are now present in map1.

7. Conclusion

In this tutorial, we explored different ways to merge two maps in Kotlin. Further, we learned about operators, such as + and +=, along with functions, such as putAll() and associateWith(), while solving the use case.

Lastly, we also leveraged the interoperability of the merge() method from the Java Map interface.

As always, the code from this article is available over on GitHub.