Stream st = Stream.of(1,2,3,4);
Does this create a stream of Integers (By inferring at runtime) or a Stream of Objects?
st.collect(Collectors.averagingInt((Integer x)->x));
This line compiles fine.
st.forEach((Integer x)-> System.out.println(x));
This line does not compile. It gives a compilation error at (Integer x), saying expected object but found Integer. Why?
Why does it not complain the same for the averagingInt method above?
averagingInt takes the ToIntFunction interface with raw reference type as <? super T>
and allowing Integer value. While forEach is taking the Consumer interface with the same raw reference type as <? super T>
and the compiler is complaining for the Integer argument value.
In Java 8, using lambda expression and Stream API we can pass processing logic of elements into methods provided by collections and now collection is responsible for parallel processing of elements and not the client. Also, parallel processing effectively utilizes multicore CPUs used nowadays.
Lambda Expressions were added in Java 8. A lambda expression is a short block of code which takes in parameters and returns a value. Lambda expressions are similar to methods, but they do not need a name and they can be implemented right in the body of a method.
Q 5 - Which of the following is correct about Java 8 lambda expression? A - Lambda expressions are used primarily to define inline implementation of a functional interface.
From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. A functional interface can have any number of default methods. Runnable, ActionListener, Comparable are some of the examples of functional interfaces.
Does this create stream of Integers (By inferring at runtime) or Stream of Objects ?
Generics do not exist at runtime, there is nothing to "infer" at runtime. Since you have used a raw type for the Stream st
- it is a Stream<Object>
if you want.
Well, even what you wrote for (and does compile):
st.collect(Collectors.averagingInt((Integer x)->x));
would not compile when you try to add the expected result:
Double i = st.collect(Collectors.averagingInt((Integer x) -> x));
I wonder if you re-write like below would make more sense:
Collector<Integer, ?, Double> collector = Collectors.averagingInt((Integer x) -> x);
Double result = st.collect(collector); // does not compile
Inference would work for Collectors.averagingInt
, but since you have used Stream as raw - everything else is raw too.
As was told above you are trying to use raw Stream. If you want to iterate across Integer then you need to specify generic for Stream.
For instance
Stream<Integer> st = Stream.of(1,2,3,4);
Then it will compile.
This probalem is equuvalent to problem with iterating across generic colection in old style
Collection values = Arrays.asList(1,2,3,4);
for(Integer v: values){
System.out.println(v);
}
The code above won't compile because values is list of objects not integers.
As for averagingInt it will compile even if you will provide a list of String. For instance
Stream st = Stream.of("1","2","3","4");
st.collect(Collectors.averagingInt((Integer x)->x));
However it will failed during runtime with ClassCastException. The difference here is that averagingInt tryes to cast all incoming types to specific and forEach just uses types as is what may cause compilation fail.
It is equivalent
ToIntFunction<? super Integer> mapper = new ToIntFunction<Integer>(){
@Override
public int applyAsInt(Integer value) {
return value;
}
};
st.collect(Collectors.averagingInt(mapper));
The anonymous class will be used inside of averagingInt and before passing args to applyAsInt method it will be cast to appropriate type (in my sample to Integer )
Another interesting thing
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With