ZetCode

Java Stream iterate

last modified May 24, 2025

This article demonstrates how to use the Java Stream iterate method to create sequential streams with defined iteration patterns.

Stream.iterate is a static factory method that creates a sequential, ordered stream by iteratively applying a function to an initial value. It's useful for creating streams of mathematical sequences, time series data, or any ordered sequence of values.

Basic iterate syntax

The iterate method has two variants:

static <T> Stream<T> iterate(T seed, UnaryOperator<T> f)
static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> f)

The first creates an infinite stream starting with seed, where each subsequent element is generated by applying f to the previous element. The second variant (Java 9+) adds a predicate to limit the stream when the condition becomes false.

Simple number sequence

In the next example, we create a simple sequence of numbers using the iterate method. This example demonstrates how to generate a finite sequence of numbers starting from a given seed and applying a function to generate subsequent values.

Main.java
void main() {

    Stream.iterate(0, n -> n + 1)
          .limit(10)
          .forEach(System.out::println);
}

This example generates numbers starting from 0, with each subsequent number incremented by 1. The limit operation is necessary to avoid infinite processing.

$ java Main.java
0
1
2
3
4
5
6
7
8
9

Finite sequence with predicate

The next example shows how to create a finite sequence using a predicate to control when the stream should stop iterating. This is useful for generating sequences that have a defined end condition.

Main.java
void main() {

    Stream.iterate(1, n -> n <= 100, n -> n * 2)
          .forEach(System.out::println);
}

This example generates powers of 2 until the value exceeds 100. The predicate n -> n <= 100 determines when the stream should stop.

$ java Main.java
1
2
4
8
16
32
64

Fibonacci sequence

Generating Fibonacci numbers using iterate.

Main.java
void main() {

    Stream.iterate(new int[]{0, 1}, t -> new int[]{t[1], t[0] + t[1]})
          .limit(10)
          .map(t -> t[0])
          .forEach(System.out::println);
}

This example generates Fibonacci numbers by maintaining state in an array. Each step produces a new array containing the next pair of Fibonacci numbers.

$ java Main.java
0
1
1
2
3
5
8
13
21
34

Date sequence

We can also use iterate to generate a sequence of dates. This is useful for creating time series data or generating a sequence of dates for analysis.

Main.java
void main() {

    Stream.iterate(LocalDate.now(), date -> date.plusDays(1))
          .limit(7)
          .forEach(System.out::println);
}

This example generates dates starting from today and continuing for 7 days. Each date is incremented by one day from the previous date.

$ java Main.java
2025-05-24
2025-05-25
2025-05-26
2025-05-27
2025-05-28
2025-05-29
2025-05-30

Conditional iteration with predicate

In the next example, we use the predicate variant of iterate to create a countdown sequence.

Main.java
void main() {

    Stream.iterate(100, n -> n > 0, n -> n - 10)
          .forEach(System.out::println);
}

This example counts down from 100 in steps of 10 until reaching 0. The predicate n -> n > 0 stops the stream when the value reaches 0.

$ java Main.java
100
90
80
70
60
50
40
30
20
10

Random walk sequence

Next, we create a random walk sequence with state.

Main.java
void main() {

    Random random = new Random();
    
    Stream.iterate(0.0, x -> x + (random.nextBoolean() ? 0.5 : -0.5))
          .limit(20)
          .forEach(System.out::println);
}

This example simulates a random walk starting at 0.0, moving up or down by 0.5 at each step randomly. The iterate method maintains the current position.

$ java Main.java
0.0
0.5
0.0
-0.5
0.0
0.5
1.0
0.5
1.0
1.5
...

Combining with other operations

We can use iterate with other stream operations.

Main.java
void main() {

    Stream.iterate(2, n -> n < 100, n -> n * n)
          .filter(n -> n % 2 == 0)
          .map(n -> "Value: " + n)
          .forEach(System.out::println);
}

This example generates squares of numbers starting from 2 until reaching 100, filters for even numbers, and formats them as strings. It shows how iterate can be combined with other stream operations.

$ java Main.java
Value: 2
Value: 4
Value: 16

Source

Java Stream iterate documentation

In this article we have explored the Java Stream iterate method. It provides a powerful way to create ordered streams with defined iteration patterns, from simple number sequences to complex stateful generators. The predicate variant adds control over when iteration should stop.

Author

My name is Jan Bodnar, and I am a passionate programmer with extensive programming experience. I have been writing programming articles since 2007. To date, I have authored over 1,400 articles and 8 e-books. I possess more than ten years of experience in teaching programming.

List all Java tutorials.