2015-02-04 2 views
2

Я не знаю, почему этот код не компилируется (случай 1)Кастинг с потоком API

List list = new LinkedList<>(); 
List<Long> longList = list.stream() 
    .map(value -> (Long) ((Map) value).get("id")) 
    .collect(Collectors.toList()); 

но этот код успешно скомпилируется (случай 2)

List list = new LinkedList<>(); 

Stream<Long> longStream = list.stream() 
    .map(value -> (Long) ((Map) value).get("id")); 

List<Long> longList = longStream.collect(Collectors.toList()); 

и этот код компиляции успешно (случай 3)

List<Object> list = new LinkedList<>(); 
List<Long> longList = list.stream() 
    .map(value -> (Long) ((Map) value).get("id")) 
    .collect(Collectors.toList()); 

Мой коллега предположить, что это связано с

Замените все параметры типа в общих типах своими границами или Object, если параметры типа являются неограниченными. Таким образом, полученный байт-код содержит только обычные классы, интерфейсы и методы.

из Java SE tutorial

Таким образом, в случае 1 список не ограничен, поэтому компилятор заменит все типы с Object.

В случае 2 мы создаем общий Stream из Long, и этот поток не может быть неограниченным. Компилятор ничего не делает.

В случае 3 у нас есть List из Object и нет замены во время компиляции.

Вопрос в том, какая реальная разница между этими тремя случаями?

+2

смешивания сырья типы дженериков никогда не является хорошей идеей ... – assylias

+0

я знаю, но это не моя идея. Hibernate criteria.list() возвращает исходный тип в некоторых случаях, и я ищу «лучший» код для сопоставления и сбора данных с помощью stream api. –

ответ

3

Ваш List list является сырым типом, и это приводит к тому, что все методы вы вызываете также и необработанные типы, даже если позже вы можете вернуть общий тип. т. е. вы отображаете() условный возвращает Stream<Long>, но компилятор видит только его как не общий Stream

Присвоение его переменной приводит к ее обобщению.

То, что я предлагаю вам сделать это

List<Map<String, Long>> list = new LinkedList<>(); 
List<Long> longList = list.stream() 
    .map(value -> value.get("id")) 
    .collect(Collectors.toList()); 
+0

Спасибо за ответ. Вы подтверждаете мою коллегу идею об очистке типа и типа. –

Смежные вопросы