Stream Reduce

The Stream class introduces many new functions that combine the stream and return a single value such as average, sum, min, max, and count etc and some user-defined functions as well. These operations are called reduction functions.

these functions are terminal operations. It aggregates or combines the Numeric streams into either some predefined reductions and can take user-defined functions as well.

package org.wesome.java8;

import java.util.OptionalDouble;
import java.util.OptionalInt;
import java.util.stream.IntStream;

class Apple {
    public static void main(String args[]) {
        List<String> apples = Arrays.asList("Macintosh", "Fuji", "Gala", "Jonagold");
        apples.stream().reduce((left, right) -> left.concat(" # ").concat(right)).ifPresent(System.out::println);

        System.out.println("-------------------sum---------------------");
        int sum = IntStream.rangeClosed(1, 5).sum();
        System.out.println("sum = " + sum);

        System.out.println("-------------------average---------------------");
        OptionalDouble average = IntStream.rangeClosed(1, 5).average();
        System.out.println("average = " + average.getAsDouble());

        System.out.println("-------------------min---------------------");
        OptionalInt min = IntStream.rangeClosed(1, 5).min();
        System.out.println("min = " + min.getAsInt());

        System.out.println("-------------------max---------------------");
        OptionalInt max = IntStream.rangeClosed(1, 5).max();
        System.out.println("max = " + max.getAsInt());

        System.out.println("-------------------count---------------------");
        long count = IntStream.rangeClosed(1, 5).count();
        System.out.println("count = " + count);
    }
}

Reduce function can be called in multiple ways such as lambda function, method reference and customer methods as well. The over loaded reduce function doesn't take a default value hence it returns the optional type because the stream can be empty as well.

package org.wesome.java8;

import java.util.OptionalInt;
import java.util.stream.IntStream;

class Apple {
    public static int add(int number1, int number2) {
        return number1 + number2;
    }

    public static void main(String args[]) {
        System.out.println("-------------------reduce with lambda---------------------");
        OptionalInt sumWithLambda = IntStream.rangeClosed(1, 5).reduce((x, y) -> x + y);
        System.out.println("sumWithLambda = " + sumWithLambda.getAsInt());

        System.out.println("-------------------reduce with Custom Method Reference---------------------");
        OptionalInt sumWithMethodReference = IntStream.rangeClosed(1, 5).reduce(Apple::add);
        System.out.println("sumWithMethodReference = " + sumWithMethodReference.getAsInt());

        System.out.println("-------------------sum With Method Reference---------------------");
        OptionalInt sumWithIdentity = IntStream.rangeClosed(1, 5).reduce(Integer::sum);
        System.out.println("sumWithIdentity = " + sumWithIdentity.getAsInt());
    }
}

reduce takes identity which is the initial value as well as the default value of the function if there is no value in the stream and a BinaryOperator as an accumulator. Since the overloaded reduce function takes identity as a default value, hence it returns numeric primitive types.

package org.wesome.java8;

import java.util.stream.IntStream;

class Apple {
    public static int add(int number1, int number2) {
        return number1 + number2;
    }

    public static void main(String args[]) {
        System.out.println("-------------------sum With Identity---------------------");
        int sumWithIdentit = IntStream.rangeClosed(1, 5).reduce(100, Integer::sum);
        System.out.println("sumWithIdentit = " + sumWithIdentit);

        System.out.println("-------------------Identity as default value---------------------");
        int sum = IntStream.empty().reduce(100, Integer::sum);
        System.out.println("sum = " + sum);
    }
}

Find min in User-defined class using Reduce function.

package org.wesome.java8;

import lombok.AllArgsConstructor;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Data
@AllArgsConstructor
class Fruit {
    int fruitId;
    String fruitName;
    int price;

    public static void main(String[] args) {
        List<Fruit> apples = new ArrayList<>();
        apples.add(new Fruit(1, "Macintosh", 3));
        apples.add(new Fruit(2, "Fuji", 1));
        apples.add(new Fruit(3, "Gala", 4));
        apples.add(new Fruit(4, "Jonagold", 2));

        Optional<Fruit> apple = apples.stream().reduce((apple1, apple2) -> apple1.getPrice() > apple2.getPrice() ? apple1 : apple2);

        apple.ifPresent(System.out::println);
    }
}

follow us on