I am starting to learn lambdas and i do not understand why java Map has:
getOrDefault(Object key, V defaultValue)
and not(working just the same, but if value is absent, then defaultValue will be taken from supplier):
getOrUseSupplier(Object key, Supplier<V> defaultValue)
Adventages i currently see of current solution:
Disadventages:
I would like to know if there is any more disadventages of using & having getOrDefault rather than getOrUseSupplier. Could you also tell me if anywhere in java libraries, there is method like this:
static <V> V getOrUseSupplier(Map<?, V> map, Object key, Supplier<V> supplier)
that tries to take Value from map, and if it does not exist then takes value from Supplier.
The Java HashMap getOrDefault() method returns the specified default value if the mapping for the specified key is not found in the hashmap. Otherwise, the method returns the value corresponding to the specified key. The syntax of the getOrDefault() method is: hashmap.get(Object key, V defaultValue)
The getOrDefault(key, defaultValue) method of Properties class is used to get the value mapped to this key, passed as the parameter, in this Properties object. This method will fetch the corresponding value to this key, if present, and return it. If there is no such mapping, then it returns the defaultValue.
Map size() Method in Java With Examples Map size() method in Java is used to get the total number entries i.e, key-value pair. So this method is useful when you want total entries present on the map. If the map contains more than Integer. MAX_VALUE elements return Integer.
Interface Map<K,V> An object that maps keys to values. A map cannot contain duplicate keys; each key can map to at most one value. This interface takes the place of the Dictionary class, which was a totally abstract class rather than an interface.
Objects.requireNonNullElseGet()
is a nice way to achieve the desired getOrUseSupplier(Object key, Supplier<V> defaultValueSupplier)
behavior.
Objects.requireNonNullElseGet(map.get(key), defaultValueSupplier));
Advantages (comparing to other solutions):
Requires Java 9.
I'd be happy to have this convenient method getOrUseSupplier()
on map itself too.
Maybe in upcoming releases...
UPD
I think that this mail from Brian Goetz is the official answer to your original question. Java designers are afraid that programmers will abuse capturing lambdas using this method.
When using the getOrDefault()
method you should keep in mind that if your second argument (the default value) throws an exception for some reason, you will get that exception thrown even if the key exists in the map, as the default value is evaluated regardless of the existence of the key. Here is an example:
private static final Map<String, Integer> RANKS = Map.of(
"A", 9,
"B", 8,
"C", 7,
"D", 6
);
public static void main(final String[] args) {
final int value1 = RANKS.getOrDefault("E", 5); // This will work
final int value2 = RANKS.getOrDefault("A", Integer.valueOf("G")); // Exception!
}
As you can see even though the key A
exists, it will still try to evaluate the default value anyway, which itself throws a NumberFormatException
in this example.
If you use that hypothetical getOrUseSupplier()
method (which unfortunately, as @Kayaman already explained, doesn't yet exist natively in Java, and you should implement it yourself), you can do this:
final int value = getOrUseSupplier(RANKS, "A", () -> Integer.parseInt("G")); // This will work
Now the exception will be thrown only if the key A
is missing.
The closest equivalent of getOrUseSupplier()
in Map
is named computeIfAbsent()
which allows for the value to be computed using the key, giving more flexibility than if it only took a Supplier
. It also stores the computed value in the Map
, unlike getOrDefault
. This is because they have distinct use cases and are not really related. While getOrDefault
is usually used to return a "safe" non-null default value (such as returning empty string instead of a null) indicating that something should be in the map, computeIfAbsent()
implies that something must be in the map, and if it's not, it needs to be created or otherwise the internal state of the program is not correct.
The following example ignores the key and just uses the supplier's value.
public static <V,T> V getOrUseSupplier(Map<T, V> map, T key, Supplier<V> supplier) {
return map.computeIfAbsent(key, k -> supplier.get());
}
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