Search code examples
kotlindictionarymutablemap

Can I get single-lookup default map behaviour in Kotlin?


Coming from C++, Kotlin's withDefault feature doesn't quite work as expected:

val m = mutableMapOf<Int, MutableList<Int>>().withDefault { mutableListOf() }
...
m.getValue(1).add(2) // does not work if m[1] == null!

Now if for performance reasons I want to do only a single lookup, how can I do that?

A way with two lookups would be

if (m[1] == null) m[1] = mutableListOf(2)
else m[1].add(2)

Is there any way with a single lookup?


Solution

  • // Create the map with some example entries
    val m = mutableMapOf(
      1 to mutableListOf(),
      2 to mutableListOf(1, 2, 3)
    )
    
    m.putIfAbsent(2, mutableListOf(789))?.add(5)
    // Will append 5 to [1, 2, 3] as the key 2 exists
    
    m.putIfAbsent(3, mutableListOf(789))?.add(5)
    // Will create a new map entry 3 to [789] as the key 3 does not exist
    
    m.toList().forEach(::println)
    

    Output:

    (1, [])
    (2, [1, 2, 3, 5])
    (3, [789])