I have the following 3 files,
A.java:
class A {
private float b;
public A(float b) {
this.b = b;
}
public float getB() {
return b;
}
}
C.java:
import java.util.Arrays;
class C {
private A[] d;
private int i = 0;
public C() {
d = new A[2];
}
public float totalB() {
return Arrays.stream(d).reduce((e, f) -> e.getB() + f.getB()).get();
}
public void addB(A b) {
d[i++] = b;
}
}
D.java:
class D {
public static void main(String[] args) {
C c = new C();
c.addB(new A(3));
c.addB(new A(5));
System.out.println(c.totalB())
}
}
I was expecting the last line in D.java to output 8, however I get this error:
error: incompatible types: bad return type in lambda expression
return Arrays.stream(d).reduce((e, f) -> e.getB() + f.getB()).get();
^
float cannot be converted to A
Why does this happen? I don't see where I'm converting the floats to the object A.
If you use array reduce on an array without any elements and don't provide initialValue, it will throw a TypeError. If the array is empty and initialValue is provided, or the array has only one element and initialValue, the reduce method will return the same value without calling the callbackfn.
const sum = values. reduce((accumulator, currentValue) => { return accumulator + currentValue; } , 0); As you can see, the reduce method executes the call back function multiple times. For each time, it takes the current value of the item in the array and sum with the accumulator.
But did you know you can reduce them to objects as well? First, a quick overview of how reduce works. The reduce method receives two arguments: a function and an initial value. The function will run run for every value in the array, and receives two arguments as well: the accumulator, or acc , and the current value .
The reduce() method executes a user-supplied "reducer" callback function on each element of the array, in order, passing in the return value from the calculation on the preceding element. The final result of running the reducer across all elements of the array is a single value.
I prefer utilizing the "sum" method as it's more readable than the general reduce
pattern. i.e.
return (float)Arrays.stream(d)
.mapToDouble(A::getB)
.sum();
This is the more idiomatic, readable and efficient approach as opposed to your approach of Arrays.stream(d).reduce(...)
...
The single argument reduce()
variant expects the final result of the reduce operation to be of the same type as the Stream
elements.
You need a different variant:
<U> U reduce(U identity,
BiFunction<U, ? super T, U> accumulator,
BinaryOperator<U> combiner);
which you can use as follows:
public float totalB() {
return Arrays.stream(d).reduce(0.0f,(r, f) -> r + f.getB(), Float::sum);
}
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