I just recently found myself wanting a version of putIfAbsent(...) in java.util.Map that you can supply some kind of factory method to, to instantiate an Object if it's not already present. This would simplify a lot of code.
Here is my modified interface:
import java.util.Map;
import java.util.function.Supplier;
/**
* Extension of the Map Interface for a different approach on having putIfAbsent
*
* @author Martin Braun
*/
public interface SupplierMap<K, V> extends Map<K, V> {
public default V putIfAbsent(K key, Supplier<V> supplier) {
V value = this.get(key);
if(value == null) {
this.put(key, value = supplier.get());
}
return value;
}
}
Now my question: Is there another (easier) way of doing this or have I just overlooked something in the Java API?
The Java HashMap putIfAbsent() method inserts the specified key/value mapping to the hashmap if the specified key is already not present in the hashmap. The syntax of the putIfAbsent() method is: hashmap.putIfAbsent(K key, V value) Here, hashmap is an object of the HashMap class.
putIfAbsent adds an element with the specified Value whereas computeIfAbsent adds an element with the value computed using the Key.
The putIfAbsent method adds the key-value pair to the map if the key is not present in the map. If the key is already present, then it skips the operation.
The get() method of Map interface in Java 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.
Isn't computeIfAbsent
what you want?
If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null.
Implementation is something like:
if (map.get(key) == null) {
V newValue = mappingFunction.apply(key);
if (newValue != null) {
map.put(key, newValue);
}
}
So it's not exactly the Supplier<V>
signature you've posted but close to that. Having key as argument in the mapping function definitely makes sense.
computeIfAbsent is not a 1:1 replacement for putIfAbsent because constraints for the returned value do not match. While putIfAbsent returns null when a new entry is created, computeIfAbsent always return the assigned value.
A default implementation as suggested above with a call to get and then put works, but it requires two lookups in the map, which destroys the idea of a performant in-situ replacement.
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