1

I created the following method that adds the given UUID value with the given Integer to teh map variable.

final Map<Integer, List<UUID>> map = new TreeMap<>();

private void addToMap(Integer key, UUID value) {
    map.computeIfAbsent(key, val -> new ArrayList<>()).add(value);
}

Normally I was tried to use map.computeIfAbsent(key, value -> new ArrayList<>()).add(value); by passing value parameter to the lambda function, it it throws "Variable 'value' is already defined in the scope" error pointing the "value" in .. value -> ... part.

My updated addToMap method is working, but I think val is pointless. So, how should this method be updated?

Jack
  • 1
  • 21
  • 118
  • 236
  • I don't think you can do much more than you've already done. Other languages use `_` for this purpose but that's a reserved keyword since Java 9 – Jeroen Steenbeeke Oct 14 '21 at 07:20
  • Thanks a lot. After asking the question, I have seen that there is a similar usage in `computeIfAbsent` method explanations. So, val is only used at that place. So, I can use it like I used. – Jack Oct 14 '21 at 07:23

1 Answers1

3

Your addToMap() method implies a wrong understanding of the parameters of the computeIfAbsent() method:

private void addToMap(Integer key, UUID value) {
    map.computeIfAbsent(key, val -> new ArrayList<>()).add(value);
}

The parameter in val -> new ArrayList<>() has nothing to do with the value that you pass into addToMap()!

If you look at the JavaDoc for Map.computeIfAbsent() you can see that the second parameter is a Function<? super K,​? extends V> - i.e. a function that takes a key and returns whatever should be stored in the map.

It would be better to write the addToMap() method as

private void addToMap(Integer key, UUID value) {
    map.computeIfAbsent(key, k -> new ArrayList<>()).add(value);
}

Note that the answer from toniedzwiedz is dangerous. It only works for a Map<Integer, ?> with keys greater than or equal to zero.

It is dangerous because it basically replaces k -> new ArrayList<>() with k -> new ArrayList<>(k) - this happens to work for maps with Integer keys and uses the key value to define the initial capacity of the ArrayList.

It will not work if k is negative (new ArrayList<>(k) will throw an IllegalArgumentException if k is negative).

It will also not work for a Map<String, UUID> because there is no ArrayList constructor that takes a String argument.

Thomas Kläger
  • 17,754
  • 3
  • 23
  • 34
  • 2
    Using `ArrayList::new` is not only dangerous because it can fail with an exception when the key is negative, it may also appear to run with no immediately recognizable issue but a horrendous performance, [until you realize something’s wrong](https://stackoverflow.com/q/35296734/2711488)… – Holger Oct 14 '21 at 12:59