Потоки Java 8: почему Collectors.toMap ведет себя по-разному для обобщенных символов с подстановочными знаками?
Предположим, что у вас есть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
это все дляMap
с использованием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: не могу найти символ
символ: метод intValue ()
location: переменная номер типа java.lang.Object
Из ошибки компилятора очевидно, чтоnumber
в лямбде трактуется какObject
а не какNumber
.
Итак, теперь на мой вопрос (ы):
При сборе подстановочной версииList
почему он не работает, как не подстановочная версияList
?Почемуnumber
переменная в лямбда считаетсяObject
вместоNumber
?