Как было сказано выше, вы пытаетесь использовать raw Stream.Если вы хотите выполнить итерацию по Integer, вам нужно указать универсальный для Stream.
Например,
Stream<Integer> st = Stream.of(1,2,3,4);
Затем он скомпилируется.
Этот вероятностный эквивалент эквивалентен проблеме с повторением общей выборки в старом стиле
Collection values = Arrays.asList(1,2,3,4);
for(Integer v: values){
System.out.println(v);
}
Приведенный выше код не будет компилироваться, поскольку значения - это список объектов, а не целые числа.
Что касается averagingInt , то он будет скомпилирован, даже если вы предоставите список строк ,Например,
Stream st = Stream.of("1","2","3","4");
st.collect(Collectors.averagingInt((Integer x)->x));
Однако во время выполнения произойдет сбой с ClassCastException.Разница здесь в том, что averagingInt пытается привести все входящие типы к конкретным, а forEach просто использует типы, что может привести к сбою компиляции.
Это эквивалентно
ToIntFunction<? super Integer> mapper = new ToIntFunction<Integer>(){
@Override
public int applyAsInt(Integer value) {
return value;
}
};
st.collect(Collectors.averagingInt(mapper));
Анонимный класс будет использоваться внутри averagingInt, и перед передачей аргументов в метод applyAsInt он будет приведен к соответствующему типу (в моем примере к Integer)
Еще одна интересная вещь
Stream st = Stream.of(1,2,3,4);
Consumer<String> stringConsumer = new Consumer<String>() {
@Override
public void accept(String o) {
}
};
st.forEach(stringConsumer); // will compile disregarding to raw type of Stream and specific Consumer
st.forEach((Integer a) -> System.out.println(a)); // will fail because os raw Stream