Extracting Substreams and Combining Streams in Java

The call stream.limit(n) returns a new stream that ends after n elements (or when the original stream ends if it is shorter). This method is particularly useful for cutting infinite streams down to size. For example,

Stream<Double> randoms = Stream.generate(Math::random).limit(100);

yields a stream with 100 random numbers.

The call stream.skip(n) does the exact opposite. It discards the first n elements. This is handy in our book reading example where, due to the way the split method works, the first element is an unwanted empty string. We can make it go away by calling skip:

Stream<String> words = Stream.of(contents.split(“\\PL+”)).skip(1);

The stream.takeWhile(predicate) call takes all elements from the stream while the predicate is true, and then stops.

For example, suppose we use the codePoints method of the preceding section to split a string into characters, and we want to collect all initial digits. The takeWhile method can do this:

Stream<String> initialDigits = codePoints(str).takeWhile(

s -> “0123456789”.contains(s));

The dropWhile method does the opposite, dropping elements while a condition is true and yielding a stream of all elements starting with the first one for which the condition was false. For example,

Stream<String> withoutInitialWhiteSpace = codePoints(str).dropWhile(

s -> s.trim().length() == 0);

You can concatenate two streams with the static concat method of the Stream class:

Stream<String> combined = Stream.concat(

codePoints(“Hello”), codePoints(“World”));

// Yields the stream [“H”, “e”, “l”, “l”, “o”, “W”, “o”, “r”, “l”, “d”]

Of course, the first stream should not be infinite—otherwise the second one wouldn’t ever get a chance.

Source: Horstmann Cay S. (2019), Core Java. Volume II – Advanced Features, Pearson; 11th edition.

Leave a Reply

Your email address will not be published. Required fields are marked *