Question 1
Stream.iterate is called with three arguments. What does this program print? ```java import java.util.stream.*; public class Main { public static void main(String[] args) { String s = Stream.iterate(1, i -> i < 20, i -> i * 3) .map(String::valueOf) .collect(Collectors.joining("-")); System.out.println(s); } } ```
A. 3-9
Wrong: this assumes the seed is not part of the stream, as if next were applied once before the first emission. The seed is always the first candidate element, so 1 is emitted.
B. 1-3-9Correct answer
Correct: the three-argument iterate tests the predicate before each emission including the seed, so 1, 3, 9 pass i < 20 and 27 fails; joined with dashes they give 1-3-9.
C. The program never terminates because Stream.iterate produces an infinite stream
Wrong: this describes the two-argument iterate(seed, next), which is infinite and needs a short-circuiting op. The three-argument overload is bounded by its predicate and is finite.
D. 1-3-9-27
Wrong: this treats the predicate as a do-while condition - emit first, test afterwards - so 27 slips out before the check fails. The predicate is a hasNext, checked before emission.
Explanation
Trace: the three-argument `Stream.iterate(seed, hasNext, next)` is the stream analogue of a `for` loop — the predicate is tested *before* each element is emitted, including the seed. So it tests 1 (< 20, emit), applies next to get 3 (< 20, emit), then 9 (< 20, emit), then 27, which fails `i < 20`, so the stream ends without emitting it. Three elements survive, `map` stringifies them and `joining("-")` glues them with a single dash between neighbours: `1-3-9`. Why the others are wrong: `1-3-9-27` treats the predicate as a do-while condition — emit first, test afterwards — so 27 slips out before the check fails. The predicate is a `hasNext`, checked before emission. `3-9` assumes the seed is not part of the stream, as if `next` were applied once before the first emission. The seed is always the first candidate element. `The program never terminates because Stream.iterate produces an infinite stream` describes the *two*-argument `iterate(seed, next)`, which is indeed infinite and needs a short-circuiting op such as `limit`. The three-argument overload (Java 9) is bounded by its predicate and is a finite stream. Exam tip: `Stream.iterate(1, i -> i < 20, i -> i * 3)` maps one-to-one onto `for (int i = 1; i < 20; i *= 3)` — seed, condition, update, condition checked first. Reverse trap: with only two arguments the stream is infinite, and a terminal op like `collect` or `count` on it hangs forever.