Java Reference
In-Depth Information
In practice, implementations of reduce() can be more sophis‐
ticated than these, and can even execute in parallel if the data
structure and operations are amenable to this.
Let's look at a quick example of a reduce() and calculate the sum of some primes:
double sumPrimes = (( double ) Stream . of ( 2 , 3 , 5 , 7 , 11 , 13 , 17 , 19 , 23 )
. reduce ( 0 , ( x , y ) -> { return x + y ;}));
System . out . println ( "Sum of some primes: " + sumPrimes );
In all of the examples we've met in this section, you may have noticed the presence
of a stream() method call on the List instance. This is part of the evolution of the
Collections—it was originally chosen partly out of necessity, but has proved to be an
excellent abstraction. Let's move on to discuss the Streams API in more detail.
The Streams API
The issue that caused the library designers to introduce the Streams API was the
large number of implementations of the core collections interfaces present in the
wild. As these implementations predate Java 8 and lambdas, they would not have
any of the methods corresponding to the new functional operations. Worse still, as
method names such as map() and filter() have never been part of the interface of
the Collections, implementations may already have methods with those names.
To work around this problem, a new abstraction called a Stream was introduced—
the idea being that a Stream object can be generated from a collection object via the
stream() method. This Stream object, being new and under the control of the
library designers, is then guaranteed to be free of method name collisions. This then
mitigates the risk of clash, as only implementations that contained a stream()
method would be affected.
A Stream object plays a similar role to an Iterator in the new approach to collec‐
tions code. The overall idea is for the developer to build up a sequence (or “pipe‐
line”) of operations (such as map, filter, or reduce) that need to be applied to the
collection as a whole. The actual content of the operations will usually be expressed
by using a lambda expression for each operation.
At the end of the pipeline, the results need to be gathered up, or “materialized” back
into an actual collection again. This is done either by using a Collector or by fin‐
ishing the pipeline with a “terminal method” such as reduce() that returns an
actual value, rather than another stream. Overall, the new approach to collections
looks like this:
stream () filter () map () collect ()
Collection -> Stream -> Stream -> Stream -> Collection
The Stream class behaves as a sequence of elements that are accessed one at a time
(although there are some types of streams that support parallel access and can be
Search WWH ::

Custom Search