Предположим, что у вас есть List чисел. Значения в List могут быть типа Integer, Double и т.д. Когда вы объявляете такой List, его можно объявить с помощью шаблона (?) или без подстановочного знака.
final List<Number> numberList = Arrays.asList(1, 2, 3D);
final List<? extends Number> wildcardList = Arrays.asList(1, 2, 3D);
Итак, теперь я хочу stream использовать List и collect все > с помощью Collectors.toMap (очевидно, приведенный ниже код является лишь примером для иллюстрации проблемы). Давайте начнем с потоковой передачи numberList:
final List<Number> numberList = Arrays.asList(1, 2, 3D, 4D);
numberList.stream().collect(Collectors.toMap(
// Here I can invoke "number.intValue()" - the object ("number") is treated as a Number
number -> Integer.valueOf(number.intValue()),
number -> number));
Но я не могу выполнить ту же операцию на wildcardList:
final List<? extends Number> wildCardList = Arrays.asList(1, 2, 3D);
wildCardList.stream().collect(Collectors.toMap(
// Why is "number" treated as an Object and not a Number?
number -> Integer.valueOf(number.intValue()),
number -> number));
Компилятор жалуется на вызов number.intValue() со следующим сообщением:
Test.java: невозможно найти символ
symbol: метод intValue()
location: переменное число типа java.lang.Object
Из ошибки компилятора очевидно, что number в лямбда рассматривается как Object вместо number.
Итак, теперь на мой вопрос (ы):
- При сборе подстановочной версии
List, почему она не работает как несимвольная версияList? - Почему переменная
numberв лямбда считаетсяObjectвместоnumber?