The Java 8 Stream API contains a set of terminal operations (such as average, sum, min, max, and count) which return one value by combining the elements of a stream. Such terminal operations are called reduction operations. In addition to those terminal operations, the JDK also provides the general-purpose reduction method – reduce()
, which this post describes.
1. A Simple Example of Stream.reduce()
Assuming we have a word stream like the following:
List<String> list = new ArrayList<String>(); list.add("java"); list.add("php"); list.add("python"); list.add("perl"); list.add("c"); list.add("lisp"); list.add("c#"); Stream<String> wordStream = list.stream(); |
We can use use the following code to get the sum of the length of strings in the list:
int s = wordStream.map(s -> s.length()) .mapToInt(Integer::new) .sum(); System.out.println(s); |
We can also use the Stream.reduce() method which is a more general method:
Stream<Integer> lengthStream = wordStream.map(s -> s.length()); Optional<Integer> sum = lengthStream.reduce((x, y) -> x + y); sum.ifPresent(System.out::println); |
Stream.reduce() take input as an accumulator function which takes two parameters: a partial result of the reduction (in this case, the sum of all processed integers so far) and the next element of the stream (in this case, an integer). It returns a new partial result. In this case, the accumulator function is a lambda expression that adds two Integer values and returns an Integer value.
Instead of using lambda expression, you can also use:
Optional<Integer> sum = lengthStream.reduce(Integer::sum); |
2. Provide Identify Value
In the previous example, the reduce() method returns an Optional
Stream<Integer> lengthStream = wordStream.map(s -> s.length()); int sum = lengthStream.reduce(0, (x, y) -> x + y); System.out.println(sum); |
The initial value must be a value for the reduce function. For all t, reduce(identity, t) and reduce(t) should return the same value, but not in the same type (One is a value, the other is an Optional).
In addition, we can also write reduce() method like the following:
int s = wordStream.reduce(0, (x, y) -> x + y.length(), (x, y) -> x + y); System.out.println(s); |
The three parameters are identify, reducer, and combiner.
– identity – identity value for the combiner function
– reducer – function for combining two results
– combiner – function for adding an additional element into a result.
Reference:
1. Stream.reduce()
nice explanation, thank u
it’s also possible to map the stream like this:
list.stream()
.mapToInt(String::length)
.reduce(Integer::sum);
Good post.
Very good post. thanks.