Search code examples
kotlinhashmapkotlin-null-safety

Bracket notation in a Map of Map in Kotlin


In Kotlin it is possible to use bracket notation with a Map, so the following code:

  val mapOfMap: Map<String, Map<String, String>> = mapOf("Key1" to mapOf("Subkey1" to "Value1", "Subkey2" to "Value2"))
  println(mapOfMap["Key1"])

prints:

{Subkey1=Value1, Subkey2=Value2}

That's great. But why can't I do the following

println(mapOfMap["Key1"]["Subkey1"])

It causes a compilation error: Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Map?

What is the proper way to handle this?


Solution

  • mapOfMap["Key1"] returns Map<String, String>?, and get operator isn't specified for nullable Map. Therefore, the following code does not compile:

    mapOfMap["Key1"]["Subkey1"]
    

    You can make it compile by creating extension get operator function with nullable Map receiver:

    operator fun <K, V> Map<K, V>?.get(key: K): V? = this?.get(key)
    

    You can also create an extension get operator function for maps of maps:

    operator fun <K1, K2, V> Map<K1, Map<K2, V>>.get(key1: K1, key2: K2): V? = get(key1)?.get(key2)
    

    And use it this way:

    mapOfMap["Key1", "Subkey1"]