Generating Primitive Streams
iterate and generate.
Generating Primitive Streams is a free Java Academy lesson on CoddyKit — lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Java Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Infinite Streams Need Limits
iterate and generate create potentially infinite streams. You must add limit (or a predicate) to make them finite.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
IntStream.iterate(1, n -> n + 1)
.limit(5)
.forEach(System.out::println);
}
}iterate with a Seed
iterate(seed, next) starts at the seed and repeatedly applies the function to the previous value.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
IntStream.iterate(2, n -> n * 2)
.limit(5)
.forEach(System.out::println);
}
}iterate with a Predicate
The three-argument iterate(seed, hasNext, next) stops automatically when the predicate is false, like a functional for-loop.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
IntStream.iterate(1, n -> n <= 100, n -> n * 3)
.forEach(System.out::println);
}
}generate with a Supplier
generate takes an IntSupplier that produces each element independently, with no dependence on the previous value.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
IntStream.generate(() -> 7)
.limit(3)
.forEach(System.out::println);
}
}Generating Random Numbers
A generate supplier can call a random source. Here each element is an independent dice roll.
import java.util.Random;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
Random rnd = new Random(42);
IntStream.generate(() -> rnd.nextInt(6) + 1)
.limit(5)
.forEach(System.out::println);
}
}iterate vs generate
Key difference:
iterate: each value derived from the previous one (sequences).generate: each value produced independently (constants, randoms).
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
int sum = IntStream.iterate(1, n -> n + 1).limit(10).sum();
System.out.println(sum);
}
}Aggregating Generated Streams
Once limited, generated streams support all normal aggregates.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
long count = IntStream.iterate(0, n -> n + 2)
.limit(50)
.filter(n -> n % 3 == 0)
.count();
System.out.println(count);
}
}Fibonacci with iterate on Object Stream
For stateful sequences like Fibonacci, use Stream.iterate over an array pair, then map back to int.
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
Stream.iterate(new int[]{0, 1}, p -> new int[]{p[1], p[0] + p[1]})
.limit(8)
.mapToInt(p -> p[0])
.forEach(System.out::println);
}
}Building an Array from a Generator
Combine a generator with toArray to build a primitive array procedurally.
import java.util.Arrays;
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
int[] squares = IntStream.iterate(1, n -> n + 1)
.limit(5)
.map(n -> n * n)
.toArray();
System.out.println(Arrays.toString(squares));
}
}Laziness Saves Work
Streams are lazy: with limit, only the needed elements are generated even from an infinite source.
import java.util.stream.IntStream;
public class Main {
public static void main(String[] args) {
int first = IntStream.iterate(10, n -> n + 10)
.filter(n -> n > 25)
.findFirst()
.getAsInt();
System.out.println(first);
}
}Prefer the Predicate Form
The predicate-based iterate is often clearer than iterate(...).limit(...) because the stopping condition lives with the generation logic.
import java.util.stream.LongStream;
public class Main {
public static void main(String[] args) {
long product = LongStream.iterate(1, n -> n <= 5, n -> n + 1)
.reduce(1, (a, b) -> a * b);
System.out.println(product);
}
}Quick Check
What happens if you call generate without a limit and then a terminal operation like forEach?
Recap
You generated primitive streams:
iteratederives each value from the previous one.generateproduces values independently from a supplier.- Both are infinite; bound them with
limitor the predicate form ofiterate. - Laziness means only needed elements are computed.
Frequently asked questions
Is the “Generating Primitive Streams” lesson free?
Yes — the full text of “Generating Primitive Streams” is free to read here on the web, and the Java Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Java Academy course, upgrade to CoddyKit PRO.
What will I learn in “Generating Primitive Streams”?
iterate and generate. You practise Java Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Java Academy?
No prior experience is required. Java Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 4 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Generating Primitive Streams” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Java Academy lesson?
Yes. Every Java Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- IntStream and LongStream
- Range and Aggregate Operations
- Mapping to and from Object Streams
- Generating Primitive Streams