Предположим, что у вас есть 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
?