Reduction is the process of applying a binary operator to every element of a stream to result in one value.
The sum()
method of an IntStream
is an example of a reduction; it applies addition to every term of the Stream, resulting in one final value:
This is equivalent to (((1+2)+3)+4)
The reduce
method of a Stream allows one to create a custom reduction. It is possible to use the reduce
method to implement the sum()
method:
IntStream istr;
//Initialize istr
OptionalInt istr.reduce((a,b)->a+b);
The Optional
version is returned so that empty Streams can be handled appropriately.
Another example of reduction is combining a Stream<LinkedList<T>>
into a single LinkedList<T>
:
Stream<LinkedList<T>> listStream;
//Create a Stream<LinkedList<T>>
Optional<LinkedList<T>> bigList = listStream.reduce((LinkedList<T> list1, LinkedList<T> list2)->{
LinkedList<T> retList = new LinkedList<T>();
retList.addAll(list1);
retList.addAll(list2);
return retList;
});
You can also provide an identity element. For example, the identity element for addition is 0, as x+0==x
. For multiplication, the identity element is 1, as x*1==x
. In the case above, the identity element is an empty LinkedList<T>
, because if you add an empty list to another list, the list that you are "adding" to doesn't change:
Stream<LinkedList<T>> listStream;
//Create a Stream<LinkedList<T>>
LinkedList<T> bigList = listStream.reduce(new LinkedList<T>(), (LinkedList<T> list1, LinkedList<T> list2)->{
LinkedList<T> retList = new LinkedList<T>();
retList.addAll(list1);
retList.addAll(list2);
return retList;
});
Note that when an identity element is provided, the return value is not wrapped in an Optional
—if called on an empty stream, reduce()
will return the identity element.
The binary operator must also be associative, meaning that (a+b)+c==a+(b+c)
. This is because the elements may be reduced in any order. For example, the above addition reduction could be performed like this:
This reduction is equivalent to writing ((1+2)+(3+4))
. The property of associativity also allows Java to reduce the Stream
in parallel—a portion of the Stream can be reduced by each processor, with a reduction combining the result of each processor at the end.