iterate and generate: Infinite Streams

Streams · lesson 19 of 42 · 4 min read

Build a stream that never ends, then bound it so the program still finishes.

Open this lesson in the learning hub

Key points

  • iterate(seed, f) yields seed, f(seed), f(f(seed)) forever. generate(s) just keeps calling the supplier.
  • The three argument iterate(seed, hasNext, next) is the for loop of streams: it carries its own stop condition.
  • A two argument iterate with no limit or takeWhile hangs the thread. Bound it before the terminal op.
  • Laziness is what makes this safe: values are produced one at a time, only when the terminal op pulls.
  • Carry a small array or record as the seed when the next value needs more than one previous value, as Fibonacci does.
  • generate suits constants, random values and counters. It has no ordering guarantee in parallel.

Example

import java.util.*;
import java.util.stream.*;

public class Main {
    public static void main(String[] args) {
        System.out.println("iterate x2   : " + Stream.iterate(1, i -> i * 2).limit(6).toList());
        System.out.println("iterate 3arg : " + Stream.iterate(1, i -> i <= 40, i -> i * 3).toList());
        System.out.println("generate     : " + Stream.generate(() -> "ping").limit(3).toList());

        // Fibonacci: carry a pair forward, then keep the first slot of each pair.
        List<Integer> fib = Stream.iterate(new int[]{0, 1}, p -> new int[]{p[1], p[0] + p[1]})
                .limit(10)
                .map(p -> p[0])
                .toList();
        System.out.println("fibonacci    : " + fib);

        // IntStream.iterate stays unboxed and takes the same 3-arg form.
        System.out.println("countdown    : " + IntStream.iterate(5, i -> i > 0, i -> i - 1).boxed().toList());

        // The bound must come before the terminal op, or the stream never ends.
        System.out.println("first 4 sq   : " + IntStream.iterate(1, i -> i + 1).limit(4).map(i -> i * i)
                .boxed().toList());
    }
}

An infinite source is safe only because something downstream stops pulling.

This is a reading copy. The full lesson — with the visual explainer, the interactive lab and a Run button for the code — lives in the Streams course, and every lesson in it is listed on the Streams contents page.