Как распознать необработанный тип

У меня есть это упражнение:

List<Integer> iList = Arrays.asList(1, 2, 3, 4, 5, 6, 7);
Predicate<Integer> p = x -> x%2 == 0; 
List newList = iList.stream()
                    .filter(p)
                    .filter(x -> x>3)
                    .collect(Collectors.toList()); 

System.out.println(newList);

На мой взгляд, newList является необработанным, а не универсальным типом, потому что он был инициализирован как List newList, а не как List<Integer>. Как можно получить нормальный результат для этого упражнения, а не ошибку компиляции?

Если я напишу:

List iList = Arrays.asList(1,2,3,4,5,6,7);
iList.stream()
     .filter(x -> x%2==0)
     .filter(x -> x>3)
     .collect(Collectors.toList());

Он не компилируется. Почему в первом случае код компилируется?

Необработанные типы совершенно законны, но очень плохая практика, о чем свидетельствует ваш второй фрагмент кода, который не компилируется.

GBlodgett 18.04.2019 20:00

Второй фрагмент не компилируется из-за простой опечатки. И идея о том, что необработанные типы приводят к ошибке компиляции (по умолчанию), просто неверна.

GhostCat 18.04.2019 20:04
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
5
2
88
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Вы правы, это необработанный тип:

List newList = iList.stream().filter(p).filter(x>x>3).collect(Collectors.toList()); 
System.out.println(newList);

Однако необработанные типы вполне допустимы и не вызовут ошибки компиляции. Они просто очень плохая практика для использования. Это демонстрируется вашим вторым фрагментом кода:

List iList= Arrays.asList(1,2,3,4,5,6,7);
iList.stream().filter(x -> x%2 ==0).filter(x -> x>3).collect(Collectors.toList());

Здесь, поскольку iList является необработанным типом, компилятор не знает, что iList содержит int, и обрабатывает их как объекты, поэтому вы не можете использовать здесь оператор %. Фактическая ошибка, которую я получаю:

bad operand types for binary operator '%'
  first type:  Object
  second type: int

bad operand types for binary operator '>'
  first type:  Object
  second type: int

Note that this is ignoring your syntax error in your lambdas. The correct syntax is x -> x > 3 and not x>x>3

Но почему код компилируется в первом случае и не компилируется во втором?

Sam 18.04.2019 20:05

@Adryr83 Adryr83 Поскольку компилятор обрабатывает содержимое как Object, поэтому вы не можете использовать для них % или >

GBlodgett 18.04.2019 20:07

Я использовал одни и те же методы в обоих случаях. Я знаю, что с необработанным типом я должен использовать только методы объекта. Но почему в первом случае компилятор компилирует? У меня должна быть ошибка компиляции в обоих случаях.

Sam 18.04.2019 20:10

@ Adryr83 Почему? Вы можете получить List<Object>. Ошибка возникает, когда вы пытаетесь использовать List<Object> как List<Integer>

GBlodgett 18.04.2019 20:11

Да, но и в первом случае у меня есть List<Object> с именем newList. В первом случае только iList является универсальным типом, а не newList.

Sam 18.04.2019 20:14

@ Adryr83 Только newList здесь необработанный тип. Единственное, что вы делаете с этим, это распечатываете его, что действительно для List<Object>

GBlodgett 18.04.2019 20:18

Хорошее объяснение @GBlodgett

Vishwa Ratna 18.04.2019 23:46

Stream распознает последовательность необработанных объектов как простой Stream<Object>. Если вы хотите рассматривать это как Stream<Integer>, вы должны явно объявить этот факт, используя Stream::mapToInt и упаковав все Stream:

List<Integer> newList = iList.stream()                    // Stream
     .mapToInt(obj -> Integer.valueOf(obj.toString()))    // IntStream
     .boxed()                                             // Stream<Integer>
     .filter(x -> x % 2 == 0) 
     .filter(x -> x > 3)
     .collect(Collectors.toList());                       // List<Integer>

В первом случае очевидно, что Stream объявляет себя Stream<Integer>, поскольку он создан из List<Integer>.


Note you have the wrong syntax of the lambda which should be x -> x % 2 == 0 with an arrow ->.

Ответ принят как подходящий

List newList — это просто возвращаемый тип цепочки потоков.

На самом деле вы работаете с List<Integer> iList, который НЕ является необработанным типом. Поэтому нет ошибки компиляции

Другие вопросы по теме