Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reduce operation on custom object in java

How to use Reduce operation for performing sum on two fields of an object.

e.g.

class Pojo
{
    public Pojo(int a, int b) {
        super();
        this.a = a;
        this.b = b;
    }
    int a ;
    int b;
    public int getA() {
        return a;
    }
    public void setA(int a) {
        this.a = a;
    }
    public int getB() {
        return b;
    }
    public void setB(int b) {
        this.b = b;
    }

}

Pojo object1 = new Pojo(1, 1);
Pojo object2 = new Pojo(2, 2);
Pojo object3 = new Pojo(3, 3);
Pojo object4 = new Pojo(4, 4);

List<Pojo> pojoList = new ArrayList<>();

pojoList.add(object1);
pojoList.add(object2);
pojoList.add(object3);
pojoList.add(object4);

I can perform sum using IntStream like this:

int sum = pojoList.stream()
                  .mapToInt(ob -> (ob.getA() + ob.getB()))
                  .sum();

I want to perform the same operation using reduce, but somehow I am not getting the syntax correct:

pojoList.stream()
        .reduce(0, (myObject1, myObject2) -> (myObject1.getA() + myObject2.getB()));
like image 878
Niraj Sonawane Avatar asked May 29 '18 10:05

Niraj Sonawane


People also ask

What is reduce operation in Java?

Reducing is the repeated process of combining all elements. reduce operation applies a binary operator to each element in the stream where the first argument to the operator is the return value of the previous application and second argument is the current stream element.

Is reduce terminal operations in Java 8?

A reduction is a terminal operation that aggregates a stream into a type or a primitive. The Java 8 Stream API contains a set of predefined reduction operations, such as average , sum , min , max , and count , which return one value by combining the elements of a stream.

How does reduce work in Java 8?

In Java, reducing is a terminal operation that aggregates a stream into a type or a primitive type. Java 8 provides Stream API contains set of predefined reduction operations such as average(), sum(), min(), max(), and count(). These operations return a value by combining the elements of a stream.

What happens if a reduction operation has no identity element?

Identity is the default result of reduction if there are no elements in the stream. That's the reason, this version of reduce method doesn't return Optional because it would at least return the identity element. Ignoring this rule will result in unexpected outcomes.


2 Answers

Well, if you want to call reduce on the IntStream:

int sum = pojoList.stream()
                  .mapToInt(ob ->(ob.getA()+ob.getB()))
                  .reduce(0, (a,b)->a+b);

Of course, the same will work on a Stream<Integer>:

int sum = pojoList.stream()
                  .map(ob ->(ob.getA()+ob.getB()))
                  .reduce(0, (a,b)->a+b);

or with a method reference:

int sum = pojoList.stream()
                  .map(ob ->(ob.getA()+ob.getB()))
                  .reduce(0, Integer::sum);

or without the map():

int sum = pojoList.stream()
                  .reduce(0, (s,ob)->s+ob.getA()+ob.getB(),Integer::sum);

In this last example, I use the variant:

<U> U reduce(U identity,
             BiFunction<U, ? super T, U> accumulator,
             BinaryOperator<U> combiner);

since the reduced value (an Integer) is different than the type of the Stream elements.

The first parameter is an identity value - 0.

The second parameter adds the getA() and getB() values of the current Pojo element to the intermediate sum.

The third parameter combines two partial sums.

like image 56
Eran Avatar answered Sep 18 '22 19:09

Eran


sum() method implementation is as follows:

public final int sum() {
    return reduce(0, Integer::sum);
}

Replacing sum() with reduce():

int sum = pojoList.stream()
                  .mapToInt(ob -> (ob.getA() + ob.getB()))
                  .reduce(0, Integer::sum);

Or, without mapToInt():

int pojoSum = pojoList.stream()
                      .reduce(0, (sum, ob) -> sum + ob.getA() + ob.getB(), Integer::sum);

For more information, see Reduction operations paragraph.

like image 36
Oleksandr Pyrohov Avatar answered Sep 20 '22 19:09

Oleksandr Pyrohov