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 Streams.
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...