Ссылка на метод в функции карты, ошибка компиляции, когда ключ имеет тип String - PullRequest
0 голосов
/ 25 апреля 2018

Context

Я хочу использовать функцию computeIfAbsent на Map. Но я получаю ошибку компиляции при использовании

  • ссылка на метод и ключ String.

Я не получаю ошибку компиляции при использовании

  • ссылка на метод и ключ Integer.
  • лямбда и ключ String.

Иллюстрация

Следующие утверждения законны :

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

Следующие утверждения запрещены :

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

Следующие утверждения законны :

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

Вопрос : Я не понимаю, почему ключ String такой особенный в сочетании со ссылкой на метод. Есть идеи?

1 Ответ

0 голосов
/ 25 апреля 2018

Когда вы звоните ArrayList::new вместо x -> new ArrayList<>(), это равняется звонку x -> new ArrayList<>(x).

Метод computeIfAbsent требует лямбда-выражения с одним лямбда-параметром в качестве второго входного аргумента или ссылки на метод, который использует один аргумент типа String.

Ваша ошибка

Ошибка компиляции: тип ArrayList не определяет ArrayList (String), который применим здесь

говорит: you trying to call constructor with one String argument. Потому что, как я сказал выше, лямбда x -> someObject.method(x) равна someObject::method. Или лямбда x -> new SomeClass(x) равна SomeClass::new.

Вы не можете использовать здесь ссылку на метод (конструктор), потому что здесь требуется метод (конструктор), который использует один параметр или лямбда-выражение. Если была лямбда без каких-либо параметров, вы сможете вызвать пустой конструктор.

...