4

Context:

I want to use the function computeIfAbsent on a Map. But, I get a compilation error when I use

  • method reference and the key is a String.

I get no compilation error when I use

  • method reference and the key is an Integer.
  • lambda and the key is a String.

Illustration:

The following statements are legal:

Map<Integer, List<Long>> map = new HashMap<>();
Integer key = Integer.valueOf(0);
Long value = Long.valueOf(2);
map.computeIfAbsent(key, ArrayList::new).add(value); // No compilation error

The following statements are illegal:

Map<String, List<Long>> map = new HashMap<>();
String key = "myKey";
Long value = Long.valueOf(2);
map.computeIfAbsent(key, ArrayList::new).add(value); // Compilation error: The type ArrayList does not define ArrayList(String) that is applicable here

The following statements are legal:

Map<String, List<Long>> map = new HashMap<>();
String key = "myKey";
Long value = Long.valueOf(2);
map.computeIfAbsent(key, x -> new ArrayList<>()).add(value); // No compilation error

Question: I don't get why a String as key is that special when combined with method reference. Any idea?

KeyMaker00
  • 6,194
  • 2
  • 50
  • 49

1 Answers1

5

When you call ArrayList::new instead of x -> new ArrayList<>() it's equals to call x -> new ArrayList<>(x).

Method computeIfAbsent requires lambda expression with one lambda parameter as second input argument, or a reference to method that consumes one argument of String type.

Your error

Compilation error: The type ArrayList does not define ArrayList(String) that is applicable here

is talking: you trying to call constructor with one String argument. Because, as I told above, lambda x -> someObject.method(x) is equal to someObject::method. Or lambda x -> new SomeClass(x) is equal to SomeClass::new.

You can't use method (constructor) reference here, because here required method (constructor) that consumes one parameter, or a lambda expression. If there was lambda without any parameters, you will be able to call empty constructor.

Peter Samokhin
  • 864
  • 1
  • 9
  • 19
  • 2
    Your answer gave me the hint that I needed: in ArrayList class there is only the following constructor: ArrayList(), ArrayList(Collection extends E> c), ArrayList(int initialCapacity). Thx – KeyMaker00 Apr 25 '18 at 13:59
  • 1
    @KeyMaker00 hmm.. I told that you use method references not as needed :) I have tried to explain what the error is. if the answer satisfies you, mark it as correct. GL :) – Peter Samokhin Apr 25 '18 at 14:02