The static Stream.iterate(T seed, UnaryOperator f) method returns Stream<T> object that emits an infinite number of values of type T, each produced by the specified UnaryOperator<T> applied to the previously emitted value. The first emitted value is the specified T seed. For example:
Stream<Integer> stream = Stream.iterate(3, i -> i + 2);
stream.limit(5).forEach(System.out::print); //prints: 357911
As you can see, we had to add the limit(long maxSize) operator. Otherwise, the stream would be infinite.
Since this trick was used quite often (rarely when an infinite stream is required), an overloaded version of this method was added in Java 9, which is
Stream.iterate(T seed, Predicate<T> hasNext, UnaryOperator<T> f)
The second parameter is a Predicate<T> is a function that accepts a value of type T (the next emitted value) and returns boolean.
This boolean value serves as a flag that indicates whether the stream should stop emitting values. For example, we can achieve exactly the same result as in the previous code snippet using this new overloaded iterate()method version as follows:
Stream<Integer> stream =
Stream.iterate(3, i -> i < 12, i -> i + 2);
stream.forEach(System.out::print); //prints: 357911
The usage of the iterate() method is quite straightforward. There is not much we can add in a way of explanation. But let’s say a few words about the UnaryOperator<T>function.
The UnaryOperator<T> interface is a specialization of the Function<T, R> interface, which takes a value of type T and returns value of type R. The UnaryOperator<T> extends Function<T, R> and inherits from it the abstract method T apply(R r). The specialization of the UnaryOperator<T> is that the type of the return value is the same as the type of the input value.
To learn more details about Java functional interfaces, refer to the following page: functional programming.
And, finally, we would like just to mention that there are corresponding iterate() methods that create numeric streams
— IntStream.iterate(int seed, IntUnaryOperator f)
— IntStream.iterate(int seed, IntPredicate hasNext, IntUnaryOperator next)
— LongStream.iterate(long seed, LongUnaryOperator f)
— LongStream.iterate(long seed, LongPredicate hasNext, LongUnaryOperator next)
— DoubleStream.iterate(double seed, DoubleUnaryOperator f)
— DoubleStream.iterate(double seed, DoublePredicate hasNext, DoubleUnaryOperator next)
In the next post, we will talk about creating a numeric streams using methods
— IntStream.range(int, int)
— IntStream.rangeClosed(int, int)
— LongStream.range(long, long)
— LongStream.rangeClosed(long, long)
See other posts on Java 8 streams and posts on other topics.
You can also use navigation pages for Java stream related blogs:
— Java 8 streams blog titles
— Create stream
— Stream operations
— Stream operation collect()
The source code of all the code examples is here in GitHub.
Send your comments using the link Contact or in response to my newsletter.
If you do not receive the newsletter, subscribe via link Subscribe under Contact.