What is the difference between Stream.iterate() and Stream.generate()?

Stream.iterate() and Stream.generate() are two static factory methods on the Stream interface used to produce infinite streams in Java 8. They differ in how each new element is computed: iterate() derives values from the previous element, while generate() produces values independently using a Supplier.

Key Points: • Stream.iterate(seed, UnaryOperator) applies a function to the previous element to compute the next one, forming a sequential, stateful chain. • Stream.generate(Supplier) pulls each element from a Supplier that takes no arguments and has no dependency on prior elements. • Both produce infinite streams, so a limit() call (or another short-circuiting operation) is required to make them usable. • iterate() is ideal for sequences like powers of two or Fibonacci numbers; generate() suits cases like random numbers or constant values. • Java 9 added an overloaded iterate(seed, hasNext, next) that supports a termination condition, unlike the Java 8 version.

Example: Stream.iterate(1, n -> n * 2).limit(5) produces 1, 2, 4, 8, 16, while Stream.generate(Math::random).limit(3) produces three unrelated random numbers.

Code Example:

Stream.iterate(1, n -> n * 2)
        .limit(5)
        .forEach(System.out::println);

Stream.generate(() -> "x")
        .limit(3)
        .forEach(System.out::println);

Interview Tip: A concise interview answer is:

"Stream.iterate() builds each element from the previous one using a seed and a function, making it good for sequences like powers of two. Stream.generate() uses a Supplier to produce elements independently of each other, which suits things like random numbers. Both are infinite streams, so you always need limit() to bound them."