This is the second post on my personal journey to learn Java 8.
With Learning Java 8 - Lambda Expressions we scratches the surface of Java 8 lambda expressions.
The current post is to get a first impression of the new java.util.stream.Stream
API.
There are various ways to create a Java 8 Stream
.
Let's start with the creation of an empty
stream (e.g. to return a meaningful default value instead of null
):
import static java.util.stream.Stream.empty;
Stream<Object> emptyStream = empty();
One of the easiest way to generate a short Stream
is to use the Stream.of
method.
Which leads us directly to the famous Hello World of Stream
:
import static java.util.stream.Stream.of;
Stream<String> helloWorld = of("Hello", "World");
Time to generate
an endless constant stream foreverFortyTwo
(from a Supplier
you should know from part I):
import static java.util.stream.Stream.generate;
import static java.util.Boolean.true;
Supplier<Integer> fortyTwo = () -> 42;
Stream<Boolean> foreverFortyTwo = generate(fortyTwo);
To generate random numbers you can do it yourself (with a method reference):
Stream<Double> randomDoubles = generate(Math::random);
or choose one of the new method of Random
to generate an IntStream
with ints
:
import java.util.stream.IntStream;
import static java.util.Random.ints;
IntStream randomInts = ints();
Speaking of new methods we continue with the Stream.iterate
method to implement infinite sequential ordered Stream
s.
We start with the natural numbers:
import static java.util.stream.Stream.iterate;
Stream<Integer> positiveIntegers = iterate(1, (seed) -> seed + 1);
positiveIntegers.limit(10).forEach(System.out::println);
Since our positiveIntegers
represent an endless Stream
we limit
the stream during printing...
With a nice trick you can easily calculate more complex functions like the Fibonacci sequence):
import static java.util.stream.Stream.iterate;
Stream<Integer> fibonacciSequence = iterate(new int[]{0, 1}, seed -> new int[]{seed[1], seed[0] + seed[1]})
.map(n -> n[0]);
We used an array to store the intermediate results of the Function
n -> n[0]
.
Afterwards we use map
to
drop those intermediate values.
Last but not least: Reduction.
Best explained by looking at the specialized reduction forms of IntStream
function | reduction equivalent |
---|---|
sum() |
reduce(0, Integer::sum) |
min() |
reduce(Integer::min) |
max() |
reduce(Integer::max) |
With this in mind we tackle the factorial 10!
in one line:
import static java.util.stream.IntStream.rangeClosed;
int factorialOfTen = rangeClosed(1, 10).reduce(1, (a, b) -> a * b);
Convert a Stream
to an Array
:
Planet[] myArray = planetStream.toArray(Planet[]::new);
There is a lot more to explore in the java.util.stream
package, but that's a story for another day...