Is there a way to run a piece of code only if the key doesn't exist in a ConcurrentHashMap
, and save the code's result to the collection?
I can't use Java 8 features because I'm developing for Android.
Also, I would like to avoid running long operations if I don't have to and I don't want to break the collection's atomic operation to do so.
computeIfAbsent() Parameters The computeIfAbsent() method takes 2 parameters: key - key with which the computed value is to be associated. remappingFunction - function that computes the new value for the specified key.
computeIfAbsent takes a mapping function, that is called to obtain the value if the key is missing. putIfAbsent takes the value directly. If the value is expensive to obtain, then putIfAbsent wastes that if the key already exists.
It's important to notice that with computeIfAbsent(), a compound operation is not necessarily atomic because updates are performed outside of the method.
HashMap get() Method in Java get() method of HashMap class is used to retrieve or fetch the value mapped by a particular key mentioned in the parameter. It returns NULL when the map contains no such mapping for the key.
HashMap computeIfAbsent() method in Java with Examples. The computeIfAbsent(Key, Function) method of HashMap class is used to compute value for a given key using the given mapping function, if key is not already associated with a value (or is mapped to null) and enter that computed value in Hashmap else null.
HashMap computeIfAbsent () method in Java with Examples. Last Updated : 24 May, 2019. The computeIfAbsent (Key, Function) method of HashMap class is used to compute value for a given key using the given mapping function, if key is not already associated with a value (or is mapped to null) and enter that computed value in Hashmap else null.
This is shown to see that there is no difference in the way entries (key-value pairs) are removed from the multi-value map when using the Java 7 way as compared to the Java 8 computeIfAbsent () way.
The compute () is a bit similar to computeIfPresent () except that when the key isn’t existent in the map, calling the compute () will raise an exception if you reference the val parameter (the current value for the key in the Map). The second compute () will throw: Exception in thread “main” java.lang.NullPointerException.
There is no exact equivalent, but the usual approach is something like this:
ConcurrentMap<Key,Value> map = ...
Value computeIfAbsent(Key k) {
Value v = map.get(k);
if (v == null) {
Value vNew = new Value(...); // or whatever else you do to compute the value
v = (v = map.putIfAbsent(k, vNew)) == null ? vNew : v;
}
return v;
}
This is pretty much functionally equivalent the computeIfAbsent
call in Java 8, with the only difference being that sometimes you construct a Value
object that never makes it into the map - because another thread put it in first. It never results in returning the wrong object or anything like that - the function consistently returns the right Value
no matter what, but if the construction of Value has side-effects*, this may not be acceptable.
The extra instances are generally not a performance problem because the initial get()
check eliminates most of the calls to putIfAbsent
. In general this approach can be considerably faster than computeIfAbsent
because that call does unnecessary locking of objects when the object already exists. Locally I measured it as 5 times faster if there are some objects that are heavily contended.
If you really need the computing behavior integrated into the map (with an internal lock held so exactly one thread creates the new object), you can use Guava's CacheBuilder
to get a LoadingCache
. It's essentially the same behavior as Java 8's CHM, but with a ton of additional configuration options.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With