Skip to content

Instantly share code, notes, and snippets.

@bseib
Last active June 15, 2020 16:38
Show Gist options
  • Save bseib/f4db307a5b4848ad1158db22a4b540e1 to your computer and use it in GitHub Desktop.
Save bseib/f4db307a5b4848ad1158db22a4b540e1 to your computer and use it in GitHub Desktop.
Map.computeIfAbsent vs recursion vs duplicate keys
package demo
val myMap = mutableMapOf<Int, String>()
fun main() {
val myKeys = listOf(1, 2, 2)
buildMap(myMap, myKeys)
println("map size=${myMap.size}") // yields 3
println("map keys size=${myMap.keys.size}") // yields 3
println("to list, size=${myMap.toList().size}") // yields 3
println("to set, size=${myMap.keys.toSortedSet().size}") // yields 2
myMap.keys.sorted().reduce { acc, key ->
key.also { if (it == acc) { println("dup => ${it}") }}
}
println(myMap)
val surpriseMe = myMap.get(2)
println("myMap.get(2) => ${surpriseMe}") // yields "string value for 2 at level 1"
}
fun buildMap(map: MutableMap<Int, String>, keyList: List<Int>, level: Int = 0) {
if ( keyList.size > 0 ) {
map.computeIfAbsent(keyList.get(0)) { key ->
buildMap(map, keyList.subList(1, keyList.size), 1 + level)
"string value for ${key} at level ${level}"
}
}
}
/* output:
map size=3
map keys size=3
to list, size=3
to set, size=2
dup => 2
{2=string value for 2 at level 2, 2=string value for 2 at level 1, 1=string value for 1 at level 0}
myMap.get(2) => string value for 2 at level 1
*/
@bseib
Copy link
Author

bseib commented Jun 15, 2020

Extension function FTW. Last one wins. Substitute assignWhenAbsent() in place of computeIfAbsent().

    fun <K, V> MutableMap<K, V>.assignWhenAbsent(key: K, compute: (key: K) -> V): V {
        return this.get(key) ?: compute.invoke(key).also { computedValue ->
            this.put(key, computedValue)
        }
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment