christophsturm
07/09/2021, 12:02 PMenleur
07/09/2021, 12:14 PMenleur
07/09/2021, 12:14 PMmutableMapOf<String, Int?>().apply {
getOrPut("b") { null}
} // {b=null}
mutableMapOf<String, Int?>().apply {
computeIfAbsent("b") { null}
} // {}dmitriy.novozhilov
07/09/2021, 12:25 PM/**
* Concurrent getOrPut, that is safe for concurrent maps.
*
* Returns the value for the given [key]. If the key is not found in the map, calls the [defaultValue] function,
* puts its result into the map under the given key and returns it.
*
* This method guarantees not to put the value into the map if the key is already there,
* but the [defaultValue] function may be invoked even if the key is already in the map.
*/
public inline fun <K, V> ConcurrentMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
// Do not use computeIfAbsent on JVM8 as it would change locking behavior
return this.get(key)
?: defaultValue().let { default -> this.putIfAbsent(key, default) ?: default }
}christophsturm
07/09/2021, 12:58 PMdmitriy.novozhilov
07/12/2021, 8:05 AMConcurrentHashMap.putIfAbsent takes a lock even if map contains key. So getOrPut provides a fastpath without taking that lock