Stream st = Stream.of(1,2,3,4);
这是否创建整数流(在运行时推断)或对象流?
st.collect(Collectors.averagingInt((Integer x)->x));
此行编译罚款。
st.forEach((Integer x)-> System.out.println(x));
该行不会编译。它提供了在(整数x)编译错误,说预期目标,但发现整数。为什么?
它为何不抱怨的averagingInt上述方法一样吗?
averagingInt采取与原始参考类型<? super T>
并允许整数值的ToIntFunction接口。同时的forEach走的是消费者接口与同一原始参考类型<? super T>
和编译器是抱怨为整数参数值。
这是否创建一个整数流(在运行时推断)或对象的流?
泛型不要在运行时存在,没有什么“推断”在运行时。既然你已经使用了Stream st
原始类型 - 这是一个Stream<Object>
如果你想。
好吧,就算你写的(和不编译):
st.collect(Collectors.averagingInt((Integer x)->x));
当您尝试添加预期的结果可能不会编译:
Double i = st.collect(Collectors.averagingInt((Integer x) -> x));
我不知道你重新写象下面这样会更有意义:
Collector<Integer, ?, Double> collector = Collectors.averagingInt((Integer x) -> x);
Double result = st.collect(collector); // does not compile
推理将工作Collectors.averagingInt
,但既然你已经使用流作为原料 - 一切是生了。
正如上面你被告知要使用原始流。如果要在整数迭代,那么你需要为流指定通用。
例如
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 tryes投下所有传入的类型来具体和foreach只是使用类型,是什么可能会导致编译失败。
它相当于
ToIntFunction<? super Integer> mapper = new ToIntFunction<Integer>(){
@Override
public int applyAsInt(Integer value) {
return value;
}
};
st.collect(Collectors.averagingInt(mapper));
匿名类将averagingInt的内部和通过参数传递给applyAsInt方法将被转换为适当的类型(我的样品中的整数)之前使用
另一个有趣的事情
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
该签名是不同的。
Collectors.averagingInt
接受ToIntFunction
,其操作collect
的返回类型被绑定到Stream
的类型,这是生的。
Stream.forEach
接受Consumer
,其直接绑定到Stream
的类型。
原始类型与您在forEach
指定类型干扰的能力,因为类型安全的,所以你导致编译错误。