Map.getOrPut: treat nulls as missing values.

This commit is contained in:
Ilya Gorbunov
2016-01-22 07:47:54 +03:00
parent a49db730a9
commit 23080f78f7
8 changed files with 21 additions and 44 deletions
@@ -196,8 +196,7 @@ internal inline fun <K, V> Map<K, V>.getOrElseNullable(key: K, defaultValue: ()
*
* @sample test.collections.MapTest.getOrPut
*/
@kotlin.jvm.JvmVersion
public inline fun <K, V: Any> MutableMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
public inline fun <K, V> MutableMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
val value = get(key)
return if (value == null) {
val answer = defaultValue()
@@ -208,21 +207,6 @@ public inline fun <K, V: Any> MutableMap<K, V>.getOrPut(key: K, defaultValue: ()
}
}
@kotlin.jvm.JvmName("getOrPutNullable")
@kotlin.jvm.JvmVersion
@Deprecated("This function will change its behavior soon not to distinguish missing keys and keys mapped to nulls.")
@kotlin.internal.LowPriorityInOverloadResolution
public inline fun <K, V> MutableMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
val value = get(key)
return if (value == null && !containsKey(key)) {
val answer = defaultValue()
put(key, answer)
answer
} else {
value as V
}
}
/**
* Returns an [Iterator] over the entries in the [Map].
*
@@ -18,15 +18,6 @@ public operator fun <K, V> MutableMap<K, V>.set(key: K, value: V): Unit {
put(key, value)
}
/**
* getOrPut is not supported on [ConcurrentMap] since it cannot be implemented correctly in terms of concurrency.
* Use [concurrentGetOrPut] instead, or cast this to a [MutableMap] if you want to sacrifice the concurrent-safety.
*/
@Deprecated("Use concurrentGetOrPut instead or cast this map to MutableMap.", level = DeprecationLevel.ERROR)
@kotlin.internal.LowPriorityInOverloadResolution
public inline fun <K, V> ConcurrentMap<K, V>.getOrPut(key: K, defaultValue: () -> V): Nothing =
throw UnsupportedOperationException("getOrPut is not supported on ConcurrentMap.")
/**
* Concurrent getOrPut, that is safe for concurrent maps.
*
@@ -36,14 +27,14 @@ public inline fun <K, V> ConcurrentMap<K, V>.getOrPut(key: K, defaultValue: () -
* 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: Any> ConcurrentMap<K, V>.getOrPut(key: K, defaultValue: () -> V): V {
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 }
}
@Deprecated("Use getOrPut instead", ReplaceWith("getOrPut(key, defaultValue)"))
@Deprecated("Use getOrPut instead", ReplaceWith("getOrPut(key, defaultValue)"), level = DeprecationLevel.ERROR)
public inline fun <K, V: Any> ConcurrentMap<K, V>.concurrentGetOrPut(key: K, defaultValue: () -> V): V {
// Do not use computeIfAbsent on JVM8 as it would change locking behavior
return this.get(key) ?: