Java Reference
In-Depth Information
boolean isParallel()
: It returns true if the stream is parallel, false otherwise. The result is
unpredictable when this method is called after invoking a terminal stream operation method.
•
S unordered()
: It returns an unordered version of the stream. If the stream is already
unordered, it returns itself. This is an intermediate operation.
The
Stream<T>
interface represents a stream of the element type
T
; for example, a
Stream<Person>
represents a
stream of
Person
objects. The interface contains methods representing intermediate and terminal operations such as
filter()
,
map()
,
reduce()
,
collect()
,
max()
,
min()
, etc. When you work with streams, you will use these methods
most of the time. I will discuss each method in detail shortly.
Note that the
Stream<T>
interface takes a type parameter
T
, which means that you can use it only to work with
the elements of the reference type. If you have to work with a stream of primitive type such as
int
,
long
, etc., using
Stream<T>
will involve an additional cost of boxing and unboxing the elements when primitive values are needed. For
example, adding all elements of a
String<Integer>
will require unboxing all
Integer
elements to
int
. The designers
of the Streams API realized this and they have provided three specialized stream interfaces called
IntStream
,
LongStream
, and
DoubleStream
to work with primitives; these interfaces contain methods to deal with primitive
values. Note that you do not have stream interfaces representing other primitive types such as
float
,
short
, etc.
because the three stream types can be used to represent other primitive type streams.
•
A Quick Example
Let's have a quick example of using streams. The code reads a list of integers and computes the sum of the squares of
all odd integers in the list.
The
stream()
method in the
Collection
interface returns a sequential stream where the
Collection
acts as the
data source. The following snippet of code creates a
List<Integer>
and obtains a
Stream<Integer>
from the list:
// Get a list of integers from 1 to 5
List<Integer> numbersList = Arrays.asList(1, 2, 3, 4, 5);
// Get the stream from the list
Stream<Integer> numbersStream = numbersList.stream();
The
filter()
method of the
Stream<T>
interface takes a
Predicate<T>
as argument and returns a
Stream<T>
with elements of the original stream for which the specified
Predicate
returns true. The following statement obtains
a stream of only odd integers:
// Get a stream of odd integers
Stream<Integer> oddNumbersStream= numbersStream.filter(n -> n % 2 == 1);
Notice the use of the lambda expression as the argument for the
filter()
method. The lambda expression
returns true if the element in the stream is not divisible by 2.
The
map()
method of the
Stream<T>
interface takes a
Function
as argument. Each element in the stream is passed to
the
Function
and a new stream is generated containing the returned values from the
Function
. The following statement
takes all odd integers and maps them to their squares:
// Get a stream of the squares of odd integers
Stream<Integer> squaredNumbersStream = oddNumbersStream.map(n -> n * n);
Finally, you need to add the squares of all odd integers to get the result. The
reduce(T identity,
BinaryOperator<T> accumulator)
method of the
Stream
interface performs a reduction operation on the stream
to reduce the stream to a single value. It takes an initial value and an accumulator that is a
BinaryOperator<T>
as
arguments. The first time, the accumulator receives the initial value and the first element of the stream as arguments,
and returns a value. The second time, the accumulator receives the value returned from its previous call and the second