Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Method reference on map function, compilation error when the key is of type String

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?

like image 717
KeyMaker00 Avatar asked Nov 01 '25 08:11

KeyMaker00


1 Answers

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.

like image 65
Peter Samokhin Avatar answered Nov 03 '25 23:11

Peter Samokhin



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!