# Reduction OperationsS2C Home « Reduction Operations

Lets start by explaining what reduction operations are! A reduction operation, which is also called a fold in functional programming parlance, takes a sequence of input elements and combines them into a single summary result by repeated application of a combining operation. This could be counting the number of elements in a stream, summing some numbers or finding the maximum value.

We have already encountered the general reduction operations `collect()` and `reduce()` in previous lessons and we have also used the specialised reduction operation `count()`. As you may have inferred from the methods mentioned so far, all reduction operations are terminal.

In this lesson we take a much closer look at all these methods as well other reduction operations methods we haven't used yet. We will start by looking at general reduction operations.

### General Reduction Operations Top

There are two general reduction operations, the `collect()` method which performs a mutable reduction operation on the elements of this stream, optionally using a `Collector` and the `reduce()` method which in its simplest form performs a reduction on the elements of this stream, using an associative accumulation function, and returns an `Optional` describing the reduced value, if any.

A mutable reduction is one where the reduced value is a mutable result container e.g. a `HashSet<E>`, and elements are incorporated by updating the state of the result rather than by replacing the result

Lets try these methods out! We will be using the `Employee` class we created in the Introducing Streams lesson to test against for this purpose.

Following is a `TestGeneralReduction` class to demonstrate use of the `collect()` and `reduce()` methods of the `Stream<E>` interface.

``````
package info.java8;

import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;

/* General reduction operations */
public class TestGeneralReduction {

public static void main(String[] args) {

/* Box and collect to list */
List<Double> doubles = DoubleStream.of(16.2, 8.06, 3.0001, 12, 16.16666)
.boxed()
.collect(Collectors.toList());
System.out.println("Doubles in List collection: " + doubles);

/* Get total salary of all staff */
Optional<Double> salary = Employee.listOfStaff().stream()
.map(Employee::getSalary)
.reduce((e1, e2) -> e1 + e2);
System.out.println("All Employee salary total is " + salary);

/* Get minimum age of all staff */
Optional<Integer> minAge = Employee.listOfStaff().stream()
.map(Employee::getAge)
.reduce(Integer::min);
System.out.println("Youngest member of staff is " + minAge);

/* Get maximum age of all staff */
int maxAge = Employee.listOfStaff().stream()
.map(Employee::getAge)
.reduce(0, Integer::max);
System.out.println("Oldest member of staff is " + maxAge);
}
}

``````

Building and running the `TestGeneralReduction` class produces the following output:

Lets go through the code.

We can't store primitives in collections as they are generic so we use the handy `boxed()` method to wrap some doubles and use the `collect` method along with `Collectors.toList()` to store the results in a `List<E>` which we print off. We look at collectors in more detail in the Stream Collectors lesson.

In the first use of `reduce()` we are using the variant that only takes one parameter, we map and total up the salary of all staff. This could have been more succinctly expressed as `.reduce(Double::sum)`

In the second use of `reduce()` we are again using the variant that only takes one parameter, we map the age and find the youngest employee.

In the third use of `reduce()` we are using the variant that takes two parameters, where the first is a default value for when the stream is empty, we map the age and find the eldest employee.

The reason the one parameter variant of `reduce()` returns an `Optional` is to remove `NullPointerException` scenarios.

You won't generally use the `reduce()` method, its a lot more efficient to use the aggregate fucntions of the primitive streams `DoubleStream`, `IntStream` and `LongStream`, such as `mapToInt()`, which don't require boxing.

### Specialised Reduction Operations Top

There are three specialised reduction operations, the `count()` method which returns the count of elements in this stream, the `min()` method which returns the minimum element of this stream according to the provided `Comparator` and the `max()` method returns the maximum element of this stream according to the provided `Comparator`.

Lets try these methods out! Once again we will be using the `Employee` class we created in the Introducing Streams lesson to test against for this purpose.

Following is a `TestSpecialisedReduction` class to demonstrate use of the `count()`, `min()` and `max()` methods of the `Stream<E>` interface.

``````
package info.java8;

import java.util.Optional;

import static java.util.Comparator.comparing;

/* Specialised reduction operations */
public class TestSpecialisedReduction {

public static void main(String[] args) {

/* Get count of people over 50 */
long count = Employee.listOfStaff().stream()
.filter(e -> e.getAge() > 50)
.count();
System.out.println("Total employees: " + count);

/* Get minimum salary of all staff */
Optional<Employee> salary = Employee.listOfStaff().stream()
.min(comparing(Employee::getSalary));
System.out.println("Lowest salary: " + salary);

/* Get maximum age of all staff */
Optional<Employee> maxAge = Employee.listOfStaff().stream()
.max(comparing(Employee::getAge));
System.out.println("Oldest member of staff: " + maxAge);
}
}

``````

Building and running the `TestSpecialisedReduction` class produces the following output:

First we filter people over 50 and then total them using the `count()` method.

Then we get the minimum salary of all staff by comparing salaries using the `min()` method which takes a `comparator` parameter.

Then we get the maximum age of all staff by comparing ages using the `max()` method which takes a `comparator` parameter. In this case we are using the `comparing()`static method of the `Comparator` class.

These methods are more efficient than using `reduce()` which could be used instead.

### Related Quiz

Streams Quiz 8 - Reduction Operations Quiz

## Lesson 8 Complete

In this lesson we looked at stream reduction operations.

## What's Next?

In the next lesson we look at stream collectors.