So I found a curiosity with Java's Map computeIfAbsent
(using java8) method and I hope someone can tell me why this is happening as I can not really follow the logic behind that issue.
So, I have a Map with a key (obviously) and the value is a list and I use the computeIfAbsent to create a new list when a key is not set yet. Now when I use an Integer as key I can use the following:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
But when I use a String as key trying to use
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
I get the error that The method computeIfAbsent(String, Function<? super String,? extends List<Object>>) in the type Map<String,List<Object>> is not applicable for the arguments (String, ArrayList::new)
. Is there just the implementation missing? Using a String key I have to use the method like that, which is then working again.
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>());
Maybe someone can enlighten me about that. Thanks :)
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.
ConcurrentHashMap is one of the most frequently used collection classes in our daily work, Its characteristic is high performance and thread-safety. However, there are two bugs that impact the performance of this familiar map. The problem is in computeIfAbsent .
HashMap<K, V> is a part of Java's collection since Java 1.2. This class is found in java. util package. It provides the basic implementation of the Map interface of Java. It stores the data in (Key, Value) pairs, and you can access them by an index of another type (e.g. an Integer).
The mapping function - Function<? super K, ? extends V> mappingFunction
- maps a key to a value, so when the key is Integer
, ArrayList::new
works, since ArrayList
has a constructor that takes an int (the initial capacity). On the other hand, it doesn't have a constructor that takes a String
.
Since the key probably shouldn't affect the initial capacity of the ArrayList
, you should not use a method reference here (in both cases). Use lambda expression.
To make it clearer:
List<Object> list = map.computeIfAbsent(1, ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent(1, k -> new ArrayList<>(k));
so it will create an ArrayList
with initial capacity of 1.
On the other hand:
List<Object> list = map.computeIfAbsent("key", ArrayList::new);
behaves similar to:
List<Object> list = map.computeIfAbsent("key", k -> new ArrayList<>(k));
where k
is a String
, so it doesn't pass compilation.
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