Calling object methods within Arrays.reduce(...)

Viewed 906

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.

3 Answers

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);
}

As mentioned in my comment above, posting another alternative where you don't need the second version of the reduce method.

public float totalB() {
    return Arrays.stream(d).map(i -> i.getB()).reduce(Float::sum).get();
}
Related