Creating Streams in Java 8
Fast recall
Quick revision
Core answer
Breadth of stream creation options beyond just the common list.stream() method
Only knowing list.stream() as a way to create streams, missing static factories and generators
Mention infinite streams with generate and iterate, and the use of limit to make them finite
Interview-ready guide
Interview answer
There are several ways to create streams in Java, each for different use cases.
The most common one is calling stream on a collection, like list-dot-stream. This works for any Collection like ArrayList or HashSet. If you're working with arrays, you use Arrays-dot-stream and pass the array variable.
This is especially useful for primitive arrays because it gives you specialized streams like IntStream. For small fixed datasets, there's Stream-dot-of where you pass the elements directly. Like Stream-dot-of-open-paren-one-comma-two-comma-three-close-paren.
This is handy for tests or quick examples. Then there are the infinite stream methods. Stream-dot-generate takes a Supplier and keeps calling it forever to produce values.
For example, Stream-dot-generate-open-paren-Math-colon-colon-random-close-paren generates an infinite stream of random numbers. You have to call limit on it to make it finite, otherwise your program just runs forever. Stream-dot-iterate is similar but for sequences where each element depends on the previous one.
You give it a seed value and a function. Like Stream-dot-iterate-open-paren-one-comma-n-arrow-n-times-two-close-paren generates one, two, four, eight, sixteen and so on. For file processing, there's Files-dot-lines which takes a Path and returns a stream of lines from the file.
This is memory-efficient because it reads the file lazily instead of loading the whole thing into memory. One important thing with Files-dot-lines is you have to close the stream properly using try-with-resources, otherwise you leak file handles.
Creating Streams in Java 8
Direct Answer
Streams can be created from Collections using list.stream(), from Arrays using Arrays.stream(arr), from static factories using Stream.of(a,b,c), from generators using Stream.generate(supplier), from iterators using Stream.iterate(seed, fn), and from files using Files.lines(path). Each method serves different use cases from in-memory data to infinite sequences.
Code Example
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
public class StreamCreationMethods {
public static void main(String[] args) throws IOException {
List<String> orders = Arrays.asList("Order1", "Order2", "Order3");
Stream<String> collectionStream = orders.stream();
String[] orderArray = {"Order1", "Order2"};
Stream<String> arrayStream = Arrays.stream(orderArray);
Stream<String> ofStream = Stream.of("Order1", "Order2");
Stream<Double> fiveRandomValues = Stream.generate(Math::random).limit(5);
Stream<Integer> tenPowersOfTwo = Stream.iterate(1, n -> n * 2).limit(10);
try (Stream<String> fileLines = Files.lines(Paths.get("orders.txt"))) {
fileLines.forEach(System.out::println);
}
}
}
Common Mistakes & Pitfalls
- Using a non-short-circuit terminal operation on an unbounded source:
Stream.generate(Math::random).forEach(...)does not finish normally. Add a finite bound or use a terminal operation whose result can be determined. - Not closing file streams:
Files.linesowns an open file resource and belongs in try-with-resources. - Using
Stream.ofwith a primitive array:Stream.of(intArray)has oneint[]element;Arrays.stream(intArray)produces anIntStream. For a reference array, generic inference can flatten it, so do not teach one blanket rule for every array type.
Check your understanding
Answer these without looking back at the article.
- What is the difference between stream() and parallelStream()?
- How do you create a stream of primitives (IntStream)?
- What is Stream.generate() used for?
Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.