Thread
#stdlib
    christophsturm

    christophsturm

    1 year ago
    what is the difference between ConcurrentMap getOrPut and computeIfAbsent?
    enleur

    enleur

    1 year ago
    computeIfAbsent does not work with nulls
    mutableMapOf<String, Int?>().apply {
        getOrPut("b") { null}
    } // {b=null}
    
    mutableMapOf<String, Int?>().apply {
        computeIfAbsent("b") { null}
    } // {}
    dmitriy.novozhilov

    dmitriy.novozhilov

    1 year ago
    /**
     * 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

    christophsturm

    1 year ago
    @dmitriy.novozhilov actually i did read the kdoc and wondered why it does not explain whats different from computeIfAbsent
    dmitriy.novozhilov

    dmitriy.novozhilov

    1 year ago
    ConcurrentHashMap.putIfAbsent
    takes a lock even if map contains
    key
    . So
    getOrPut
    provides a fastpath without taking that lock