Java Reference
In-Depth Information
used to process larger collections in a naturally multithreaded way). In a similar way
to an
Iterator
, the
Stream
is used to take each item in turn.
As is usual for generic classes in Java,
Stream
is parameterized by a reference type.
However, in many cases, we actually want streams of primitive types, especially ints
and doubles. We cannot have
Stream<int>
, so instead in
java.util.stream
there
are special (nongeneric) classes such as
IntStream
and
DoubleStream
. These are
known as
primitive specializations
of the
Stream
class and have APIs that are very
similar to the general
Stream
methods, except that they use primitives where appro‐
priate.
For example, in the
reduce()
example, we're actually using primitive specialization
over most of the pipeline.
Lazy evaluation
In fact, streams are more general than iterators (or even collections), as streams do
not manage storage for data. In earlier versions of Java, there was always a presump‐
tion that all of the elements of a collection existed (usually in memory). It was possi‐
ble to work around this in a limited way by insisting on the use of iterators every‐
where, and by having the iterators construct elements on the fly. However, this was
neither very convenient or that common.
By contrast, streams are an abstraction for managing data, rather than being con‐
cerned with the details of storage. This makes it possible to handle more subtle data
structures than just finite collections. For example, infinite streams can easily be
represented by the
Stream
interface, and can be used as a way to, for example, han‐
dle the set of all square numbers. Let's see how we could accomplish this using a
Stream
:
public
class
SquareGenerator
implements
IntSupplier
{
private
int
current
=
1
;
@Override
public
synchronized
int
getAsInt
()
{
int
thisResult
=
current
*
current
;
current
++;
return
thisResult
;
}
}
s
IntStream
squares
=
IntStream
.
generate
(
new
SquareGenerator
());
PrimitiveIterator
.
OfInt
stepThrough
=
squares
.
iterator
();
for
(
int
i
=
0
;
i
<
10
;
i
++)
{
System
.
out
.
println
(
stepThrough
.
nextInt
());
}
System
.
out
.
println
(
"First iterator done..."
);
a
// We can go on as long as we like...
for
(
int
i
=
0
;
i
<
10
;
i
++)
{