Page 1 of 1
About Question enthuware.ocpjp.v8.2.1859 :
Posted: Tue Oct 11, 2016 8:10 am
by lucian
I have two questions:
1. Why can the reduce method from a Stream<Integer> can auto-unbox to a double, when it's returning an Integer ?
double sum = ls.stream().reduce(0, (a, b) -> a + b);
Code: Select all
java.util.stream.Stream
T reduce(T identity, BinaryOperator<T> accumulator);
2. Why can the sum method in IntStream return a double ?
double sum = ls.stream().mapToInt(x -> x).sum();
Code: Select all
java.util.stream.IntStream
int sum();
Re: About Question enthuware.ocpjp.v8.2.1859 :
Posted: Tue Oct 11, 2016 9:05 am
by admin
1. It is not auto-unboxing to int. It is doing automatic widening of int to double. Remember that you don't need any cast to assign an int to double.
2. Same reason as above.
Re: About Question enthuware.ocpjp.v8.2.1859 :
Posted: Thu Sep 26, 2019 3:36 am
by RobinDRG
Hi Paul, I made the following trial, but still don't understand why the compiler gives me an error since the variables sum3 and sum4 outside the lambda expression are not even initialized
Code: Select all
double sum3;ls.stream().peek(x->{sum3=sum3+x;}).forEach(y->{});
System.out.println(sum3);
double sum4;ls.stream().forEach(a->{sum4=sum4+a;});
System.out.println(sum4);
Re: About Question enthuware.ocpjp.v8.2.1859 :
Posted: Thu Sep 26, 2019 3:42 am
by admin
What is the error message? It will tell you exactly what is wrong.
Re: About Question enthuware.ocpjp.v8.2.1859 :
Posted: Thu Sep 26, 2019 6:33 am
by RobinDRG
I tried to just declare the variable to go one step further and try to understand why the compiler consider the variable sum outside(initialized one single time/only declared) as non-effectively final
Code: Select all
Q4_Streams.java:18: error: variable sum3 might not have been initialized
double sum3;ls.stream().peek(x->{sum3=sum3+x;}).forEach(y->{});
^
Q4_Streams.java:19: error: variable sum3 might not have been initialized
System.out.println(sum3);
^
Q4_Streams.java:20: error: variable sum4 might not have been initialized
double sum4;ls.stream().forEach(a->{sum4=sum4+a;});
^
Q4_Streams.java:21: error: variable sum4 might not have been initialized
System.out.println(sum4);
^
Q4_Streams.java:18: error: local variables referenced from a lambda expression must be final or effectively final
double sum3;ls.stream().peek(x->{sum3=sum3+x;}).forEach(y->{});
^
Q4_Streams.java:20: error: local variables referenced from a lambda expression must be final or effectively final
double sum4;ls.stream().forEach(a->{sum4=sum4+a;});
/code]
Re: About Question enthuware.ocpjp.v8.2.1859 :
Posted: Thu Sep 26, 2019 7:05 am
by admin
1. Well, local variables have to be initialized explicitly. In your code, sum3 isn't initialized. What value do you think the JVM will use while computing the expression sum3=sum3+x; for the first time? This is standard OCAJP stuff

2. If you want to use a local variable within a lambda expression, it also has be effectively final. Which means, you can't modify its value. What do you think sum3=sum3+x; is doing?
Re: About Question enthuware.ocpjp.v8.2.1859 :
Posted: Thu Sep 26, 2019 12:34 pm
by RobinDRG
Okay, many thanks. I thought that effectively-final was referring to variables that didn't change its value outside the lambda expression. I understand it now, you can't reassign the value at all