как распознать сырой тип - PullRequest
0 голосов
/ 18 апреля 2019

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

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());

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

Ответы [ 3 ]

4 голосов
/ 18 апреля 2019

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>

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


Обратите внимание, что у вас неправильный синтаксис лямбды, который должен быть x -> x % 2 == 0 со стрелкой ->.

2 голосов
/ 18 апреля 2019

List newList - это просто тип возврата цепочки потоков.

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

2 голосов
/ 18 апреля 2019

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

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

Обратите внимание, что это игнорирует синтаксическую ошибку в ваших лямбдах.Правильный синтаксис: x -> x > 3, а не x>x>3

...