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."