List list = new ArrayList();
Stream<Object> stream = list.stream();
// маппинг так для примера
List<String> collect = stream.map(obj -> obj.toString())
.collect(toList());
Что я упустил в дженериках? Эта конструкция валидна, но убирая дженерик у стрима Stream stream = list.stream(); уже не валидна?
Или же так, зачем это кастование? (List<Object>) list
List<String> collect = ((List<Object>) list).stream.map(obj -> obj.toString())
.collect(toList());
Ответ дан здесь, но так как это StackOverflow на русском, приведу перевод:
stream(), map(), collect() и все другие stream методы завязаны на дженериках. Если опустить их использование, то все сопутствующие дженерики в библиотеках также будут опущены и все структуры превратятся в обычные интерфейсы без указания типа. К примеру, если вы используете List<String>, то вызвав метод stream(), получите Stream<String>.
Однако если вы вызовите stream() у объекта с типом List без указания типа, то вернётся объект Stream.
Метод map() в этом же случае имеет следующее объявление:
<R> Stream<R> map(Function<? super T,? extends R> mapper)
Но если учитывать тот факт, что тип не был указан, он будет приведён к виду:
Stream map(Function mapper)
Таким образом, в результате map() вернёт объект Stream. Что также помешает правильно отработать функции collect(), которая из вида:
<R> R collect(Supplier<R> supplier,
BiConsumer<R,? super T> accumulator,
BiConsumer<R,R> combiner)
Превратится в:
Object collect(Supplier supplier,
BiConsumer accumulator,
BiConsumer combiner)
Тем самым теряется объявление List и List<String> соответственно. Что и вызывает ошибку компиляции.
В итоге можно привести данный объект к необходимому виду, однако данный вид приведения вызовет предупреждение unchecked casts, так как компилятор не знает, правильно ли вы привели тип.
Если вы используете raw type Stream stream, то generics-и пропадают во всех методах Stream, и метод collect в частности начинает возвращать просто Object. При желании, конечно, можно привести результат выполнения метода collect к List<String>:
List<String> collect = (List<String>)stream.map(obj -> obj.toString())
.collect(Collectors.toList());
Аналогично с приведением списка к List<Object>: либо итоговый Stream будет параметризованным, либо окажется raw type с той же самой проблемой.
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости