getOrPutIfNull

inline fun <K, V> MutableMap<K, V>.getOrPutIfNull(key: K, crossinline defaultValue: () -> V): V(source)

Returns the value for the given key if the value is present and not null. Otherwise, calls the defaultValue function, puts its result into the map under the given key, and returns the call result.

In contrast to getOrPutIfMissing, this function puts and returns the result of the defaultValue function if the key is mapped to a null value.

When the given key is not in this map or is mapped to a null, the result of defaultValue, even if null, is put into the map under the key. If defaultValue throws an exception, the exception is rethrown.

Note that the operation is not guaranteed to be atomic if the map is being modified concurrently.

Since Kotlin

2.4

Throws

if the specified key or the result of defaultValue is null, and this map does not support null keys or values.

Samples

import kotlin.test.*
import java.util.*

fun main() { 
   //sampleStart 
   val map = mutableMapOf<String, Int?>()

println(map.getOrPutIfNull("x") { 2 }) // 2
// subsequent calls to getOrPutIfNull do not evaluate the default value
// since the first getOrPutIfNull has already stored value 2 in the map
println(map.getOrPutIfNull("x") { 3 }) // 2

// however, null value mapped to a key is treated the same as the missing value
println(map.getOrPutIfNull("y") { null }) // null
// so in that case the default value is evaluated
println(map.getOrPutIfNull("y") { 42 }) // 42 
   //sampleEnd
}
inline fun <K, V> ConcurrentMap<K, V>.getOrPutIfNull(key: K, crossinline defaultValue: () -> V): V(source)

Returns the value for the given key if the value is present and not null. Otherwise, calls the defaultValue function, puts its result into the map under the given key, and returns the call result.

In contrast to getOrPutIfMissing, this function puts and returns the result of the defaultValue function if the key is mapped to a null value.

When the given key is not in this map or is mapped to a null, the result of defaultValue, even if null, is put into the map under the key. If defaultValue throws an exception, the exception is rethrown.

This function guarantees not to put the new value into the map if the key is already associated with a non-null value. However, the defaultValue function may still be invoked.

This function relies on ConcurrentMap.computeIfAbsent. Therefore, ConcurrentMap implementations that support null values must override the default computeIfAbsent implementation, so that the result of the mappingFunction is put into the map both when there is no existing value for the key and when the key is associated with a null value.

Since Kotlin

2.4

Throws

if the specified key or the result of defaultValue is null, and this concurrent map does not support null keys or values.

Samples

import kotlin.test.*
import java.util.*

fun main() { 
   //sampleStart 
   val map = mutableMapOf<String, Int?>()

println(map.getOrPutIfNull("x") { 2 }) // 2
// subsequent calls to getOrPutIfNull do not evaluate the default value
// since the first getOrPutIfNull has already stored value 2 in the map
println(map.getOrPutIfNull("x") { 3 }) // 2

// however, null value mapped to a key is treated the same as the missing value
println(map.getOrPutIfNull("y") { null }) // null
// so in that case the default value is evaluated
println(map.getOrPutIfNull("y") { 42 }) // 42 
   //sampleEnd
}