When trying to answer a different question, I found that my code only compiles if I explicitly give the type arguments (Whatever the code calculates does not make sense, I know):
public Double calculateResult(int value) {
return 0.0d;
}
private void init2() {
List<Callable<Double>> list = IntStream.range(1, 99)
.<Callable<Double>>mapToObj(value -> (() -> calculateResult(value)))
.collect(Collectors.toList());
}
When removing the type arguments <Callable<Double>>
from the mapToObj
, it does not compile, and gives the error that it
cannot infer the type variable by itself
It neither can infer the arguments if I change it to use a Supplier<Double>
or a DoubleSupplier
.
Why can it not infer the type arguments?
Update, I am compiling it with Netbeans 8.0, have not checked it with the javac compiler yet.
This is my understanding what is going on.
The problem is that you expect the compiler to use expected assignment type, in this case List<Callable<Double>>
, to infer the type arguments. However, the .mapToObj
isn't the last statement in the chain and it doesn't return a List
.
This code below works though, because here the compiler can match the result of the .mapToObj
call to what you have declared as the return type, and therefore it can infer the type arguments for the stream.
Stream<Callable<Double>> temporaryVariable = IntStream.range(1, 99)
.mapToObj(value -> (() -> calculateResult(value)));
List<Callable<Double>> list = temporaryVariable.collect(Collectors.toList());
Because it is not the last statement in the chain, if I were a compiler I wouldn't really like to go through all the possible values of Stream<?>
(which essentially is the return type of .mapToObj
) to find one call that would match the next call to return List<Callable<Double>>
.
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