Java Reference
In-Depth Information
Are you surprised by the output? You do see numbers in the output. The input stream to the
map()
method
contains three integers: 1, 2, and 3. The
map()
method produces one element for each element in the input stream.
In this case, the
map()
method produces a
Stream<Integer>
for each integer in the input stream. It produces three
Stream<Integer>
s. The first stream contains 1 and 1; the second one contains 2 and 4; the third one contains 3 and 9.
The
forEach()
method receives the
Stream<Integer>
object as its argument and prints the string returned from its
toString()
method. You can call the
forEach()
on a stream, so let's nest its call to print the elements of the stream of
streams, like so:
Stream.of(1, 2, 3)
.map(n -> Stream.of(n, n * n))
.forEach(e -> e.forEach(System.out::println));
1
1
2
4
3
9
You were able to print the numbers and their squares. But you have not achieved the goal of getting those
numbers in a
Stream<Integer>
. They are still in the
Stream<Stream<Integer>>
. The solution is to use the
flatMap()
method instead of the
map()
method. The following snippet of code does this:
Stream.of(1, 2, 3)
.flatMap(n -> Stream.of(n, n * n))
.forEach(System.out::println);
1
1
2
4
3
9
Figure
13-8
shows the pictorial view of how the
flatMap()
method works in this example. If you still have doubts
about the workings of the flatMap operation, you can think of its name in the reverse order. Read it as mapFlat, which
means “map the elements of the input stream to streams, and then flatten the mapped streams.”
1, 1
1
4, 2
forEach
3, 2, 1
2
9, 3, 4, 2, 1, 1
1, 2, 3
3
9, 3
flatMap
Figure 13-8.
Flattening a stream using the flatMap() method