A stream transformation produces a stream whose elements are derived from those of another stream. You have already seen the fitter transformation that yields a new stream with those elements that match a certain condition. Here, we transform a stream of strings into another stream containing only long words:
List<String> words = …;
Stream<String> tongWords = words.stream().fitter(w -> w.tength() > 12);
The argument of filter is a Predicate<T>—that is, a function from T to boolean.
Often, you want to transform the values in a stream in some way. Use the map method and pass the function that carries out the transformation. For example, you can transform all words to lowercase like this:
Stream<String> lowercaseWords = words.stream().map(String::toLowerCase);
Here, we used map with a method reference. Often, you will use a lambda expression instead:
Stream<String> firstLetters = words.stream().map(s -> s.substring(0, 1));
The resulting stream contains the first letter of each word.
When you use map, a function is applied to each element, and the result is a new stream with the results. Now, suppose you have a function that returns not just one value but a stream of values. Here is an example—a method that turns a string into a stream of strings, namely the individual code points:
public static Stream<String> codePoints(String s)
var result = new ArrayList<String>();
int i = 0;
while (i < s.length())
int j = s.offsetByCodePoints(i, 1);
i = j;
This method correctly handles Unicode characters that require two char values because that’s the right thing to do. But you don’t have to dwell on that.
For example, codePoints(“boat”) is the stream [“b”, “o”, “a”, “t”].
Now let’s map the codePoints method on a stream of strings:
Stream<Stream<String>> result = words.stream().map(w -> codePoints(w));
You will get a stream of streams, like [. . . [“y”, “o”, “u”, “r”], [“b”, “o”, “a”, “t”], . . .]. To flatten it out to a single stream [. . . “y”, “o”, “u”, “r”, “b”, “o”, “a”, “t”, . . .] , use the flatMap method instead of map:
Stream<String> flatResult = words.stream().flatMap(w -> codePoints(w));
// Calls codePoints on each word and flattens the results
Source: Horstmann Cay S. (2019), Core Java. Volume II – Advanced Features, Pearson; 11th edition.