Java 8 Reduction

15 October 2014
By Gonçalo Marques
 
java java8
In this article we will cover functional programming style reductions introduced by Java 8.

Introduction

Reduction assumes an important role in functional programming. It is usually executed as the last step of a sequence of functional operations that are executed over a stream of elements and produces a final result. This result may be a single result (ex: sum, average, or any other arbitrary operation) or a collection of results (ex: word count in a document, grouped by word).

In this article we will see how to perform reductions in Java. Keep in mind that we will only cover reductions that produce a single result. Reductions that produce results in the format of collections will be covered in the next article.

Java Reduction

We start by defining a collection that will serve as the data source for the following reductions:

Data source

List<Integer> integerList = Arrays.asList(new Integer[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 });

Now let's perform a reduction that will sum all the even numbers that are present in the original collection:

Reduction that sums all even numbers

int result = integerList
    .stream()
    .filter((i) -> i % 2 == 0)
    .reduce(0, (i1, i2) -> i1 + i2);

// Will print 20
System.out.println(result);

Here the reduce operation accepts two arguments: the first is the identity, that represents the base case, or the initial value. The base case will be the default value if the stream is empty. Since we are adding up integer values we define the base case as zero.

The second argument is the accumulator which also takes two arguments: the first is the current partial result of the reduction. The second argument is the current item of the stream that is actually being processed. The accumulator must return a result that represents a new partial result.

In our example, the accumulator adds the current partial result to the current stream item. Since the initial partial result - or the base case - is zero, the final result will be the sum of the filtered stream items: 20.

We may also omit the first argument of the reduce operation:

Reduction omitting the initial value

Optional<Integer> result = integerList
    .stream()
    .filter((i) -> i % 2 == 0)
    .reduce((i1, i2) -> i1 + i2);

// Will print 20
System.out.println(result.isPresent() ? result.get() : null);

If the initial value argument is omitted from the reduce operation, the first stream element to be processed will be used as the initial value. Since the stream may be empty, the return type of this kind of reduction must be of type Optional (if the stream is empty and no initial value is specified, the reduction will return an Optional without any wrapped value).

More info about the Optional type in Java 8 Optional.

Reference

Reduction (The Java(TM) Tutorials - Collections - Aggregate Operations)

Related Articles

Comments

About the author
Gonçalo Marques is a Software Engineer with several years of experience in software development and architecture definition. During this period his main focus was delivering software solutions in banking, telecommunications and governmental areas. He created the Bytes Lounge website with one ultimate goal: share his knowledge with the software development community. His main area of expertise is Java and open source.

GitHub profile: https://github.com/gonmarques

He is also the author of the WiFi File Browser Android application: