1. Introduction

As developers, we know that a Map is an important data structure that we can use to accomplish many programming tasks. A typical example may involve modifying a map entry in place.

In this tutorial, we’ll explore various ways to change or modify a map entry in place in Kotlin.

2. Using the MutableMap Interface

The simplest way to modify a map entry in place is to use the MutableMap interface. This interface extends the Map interface and provides additional methods for modifying the map.

2.1. Using the put() Method

To modify a map entry, we can use the put() method, which replaces the value associated with the specified key:

@Test
fun `modifies mutable map entry using put method`() {
    val map = mutableMapOf("key1" to "value1", "key2" to "value2")
    map.put("key1", "new value")

    assertEquals("new value", map["key1"])
}

In this code snippet, we use the mutableMapOf() method to construct a map containing two entries. Next, we modify the value associated with key1 using the put() method. Indeed, we often use this method to add entries to a map, however, when we use this method with an existing key, the corresponding value will be overwritten. Finally, using assertion, we can confirm that key1 is associated with the updated value.

2.2. Using the Bracket Operator

Kotlin provides the bracket operator, an operator overload for the set() method. We can use this method for adding and modifying map entries. Specifically, we can use it to modify map entries in place:

@Test
fun `modifies mutable map entry using bracket operator`() {
    val map = mutableMapOf("key1" to "value1", "key2" to "value2")
    map["key1"] = "new value"

    assertEquals("new value", map["key1"])
}

In the above code, we modify the value associated with the key1 key using the bracket operator.

This technique is a simplified version of the previous approach, using the bracket operator instead of the put() method.

3. Using the replace() Method

Additionally, we can leverage the replace() method to replace the value associated with a key in a map. This method accepts two arguments:  the key and the new value. If the key is present in the map, the value is overwritten. If the key is not present, this method will have no effect:

@Test
fun `modifies mutable map entry using replace method`() {
    val map = mutableMapOf("key1" to "value1", "key2" to "value2")
    map.replace("key1", "new value")

    assertEquals("new value", map["key1"])
}

In the above unit test, we modify the value associated with the key1 key using the replace() method. Finally, we use the assertEquals() method to ensure that the value associated with the key1 key has been updated correctly.

4. Using the compute() Method

Another way to update a value in a Map involves using the compute() method. The compute() method also accepts two arguments: the key and a lambda function. In principle, this updates the value associated with the key based on the lambda function:

@Test
fun `modifies mutable map entry using compute method`() {
    val map = mutableMapOf("key1" to "value1", "key2" to "value2")
    map.compute("key1") { _, _ -> "new value" }

    assertEquals("new value", map["key1"])
}

In the code above, we call the compute() method with the key1 key and a lambda expression. The lambda function takes two parameters — the key and the current value associated with the key. We don’t use the lambda parameters, so we replace them with underscores to indicate they are unused. If the key is not in the map, the lambda function receives null as the current value.

The lambda function returns the string “new value”, which is the new value that should be associated with the key1 key. The compute() method then updates the value associated with the key1 key with the new value returned by the lambda function.

It’s worth mentioning that the c**ompute() method replaces the current value associated with the key with the new value returned by the lambda function, regardless of whether the key is present in the map.

4.1. Using the computeIfPresent() Method

Alternatively, we can use the computeIfPresent() method to update a value in a Map. This method also accepts the key as a parameter and a lambda function to update a value conditionally:

@Test
fun `modifies mutable map entry using computeIfPresent method`() {
    val map = mutableMapOf("key1" to "value1", "key2" to "value2")
    map.computeIfPresent("key1") { key, value ->
        if (value == "value1") "new value"
        else value
    }

    assertEquals("new value", map["key1"])
}

We wish to update the value associated with the key1 key, so we use the computeIfPresent() method and provide the key as an argument. Furthermore, if the value associated with the key is “value1”, the lambda function will update the value to “new value”. Otherwise, the lambda will return the existing value.

The computeIfPresent() method only updates the value if the key is already in the map. If the key is not in the map, the lambda function is not called and the method has no effect.

5. Conclusion

In this article, we explored various methods to perform in-place modification of a map entry in Kotlin. We made use of the put(), replace(), compute(), and computeIfPresent() methods and the assignment operator techniques to modify map entries according to our needs.