skip to content

Stream Creation Sources

Where streams come from: collections, arrays, Stream.of, the infinite iterate and generate forms, IntStream ranges, and Files.lines. Interviewers use infinite sources to check you know they need a limit or short-circuit to ever terminate.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What are the common ways to create a Stream in Java from existing data such as a collection, an array, or a few known values?

level: juniorimportance: must knowfreq 78%

answer

  1. Collection.stream() / parallelStream()
  2. Arrays.stream(arr) has primitive overloads
  3. Stream.of(varargs) — array-spread trap
  4. Maps: stream entrySet/keySet/values
  5. Stream.empty() as a null-free default

basics

~10 s

Call collection.stream() on a List, Set, or Map's entries; use Arrays.stream(array) for arrays; Stream.of(a, b, c) for a handful of values; and Stream.empty() for an empty stream.

solid answer

~30 s

The everyday factory methods are: Collection.stream() (and parallelStream()) on any List/Set/Queue; Arrays.stream(arr) for an array, which also has primitive overloads (int[], long[], double[]) returning IntStream/LongStream/DoubleStream; Stream.of(v1, v2, ...) for a fixed set of values (it is varargs, so Stream.of(array) of objects wraps the whole array as one stream); and Stream.empty() for a zero-element stream, handy as a neutral default. For primitives there are also IntStream.of, LongStream.of, etc. Maps have no stream() directly, so you stream map.entrySet(), map.keySet(), or map.values(). These all build a finite, sized stream over an existing source, which lets the pipeline parallelize and size efficiently.

code

java · 17 lines
java
List<String> list = List.of("a", "b", "c");
String[] arr = {"x", "y"};
int[] nums = {1, 2, 3};

Stream<String> fromList  = list.stream();
Stream<String> fromArray = Arrays.stream(arr);
Stream<String> fromVals  = Stream.of("p", "q");
Stream<String> none      = Stream.empty();

// Primitive, no boxing:
IntStream ints = Arrays.stream(nums);        // [1,2,3]
// Trap: this is a Stream<int[]> of length 1, NOT a stream of ints:
Stream<int[]> oops = Stream.of(nums);

// Maps have no stream(); stream a view:
Map<String,Integer> m = Map.of("a", 1);
m.entrySet().stream().forEach(e -> System.out.println(e.getKey()));

go deeper

for a junior

Knows collection.stream(), Arrays.stream, Stream.of, and Stream.empty() and can pick the right one for collections vs arrays vs literals.

for a middle

Adds the Map-view detail, the Stream.of array-spread trap, and the primitive Arrays.stream overloads to avoid boxing.

for a senior

Explains why sized sources matter for parallelism and sizing, and reaches for IntStream/LongStream for numeric work and Stream.empty() as a null-free contract.

for a principal

Frames stream creation as choosing a source whose Spliterator characteristics (SIZED/SUBSIZED) the pipeline exploits, and sets API conventions (return empty, never null) across a codebase.

## What a Stream is A **Stream** in Java (`java.util.stream.Stream`) is a *lazily-evaluated pipeline* over a sequence of elements. It is **not** a data structure — it does not store elements; it carries them from a **source** through zero or more **intermediate operations** (like `map`, `filter`) to a **terminal operation** (like `collect`, `forEach`) that triggers the work. Because a stream needs a source to pull elements from, the first question is always: *how do I create one?* ## Creating from a Collection Every `java.util.Collection` (so `List`, `Set`, `Queue`, ...) has a default method `stream()`: ```java List<String> names = List.of("Ann", "Bo"); Stream<String> s = names.stream(); ``` There is also `parallelStream()`, which produces a stream that may split work across threads. A **Map is not a Collection**, so it has no `stream()`. You stream one of its *views*: `map.entrySet().stream()`, `map.keySet().stream()`, or `map.values().stream()`. ## Creating from an Array `Arrays.stream(array)` turns an array into a stream: ```java String[] arr = {"a", "b"}; Stream<String> s = Arrays.stream(arr); ``` Crucially, `Arrays.stream` is **overloaded for primitive arrays**: `Arrays.stream(int[])` returns an `IntStream`, `Arrays.stream(long[])` a `LongStream`, `Arrays.stream(double[])` a `DoubleStream`. These primitive streams avoid boxing each element into an `Integer`/`Long`/`Double` object. `Arrays.stream` also has range overloads, e.g. `Arrays.stream(arr, 2, 5)` streams a sub-range. ## Creating from known values: Stream.of `Stream.of(...)` is a **varargs** factory for a fixed, small set of values: ```java Stream<Integer> s = Stream.of(1, 2, 3); ``` The varargs nature creates a subtle trap. If `T` is an object type, `Stream.of(objectArray)` is interpreted as *spreading* the array, so each element becomes a stream element. But `Stream.of(intArray)` — where `intArray` is `int[]` — does **not** spread, because `int[]` is itself a single Object; you get a `Stream<int[]>` with **one** element (the whole array). To stream the ints, use `Arrays.stream(intArray)` or `IntStream.of(intArray)`. ## The empty stream `Stream.empty()` returns a stream with zero elements. It is useful as a safe default — e.g. returning `Stream.empty()` instead of `null` from a method so callers can always chain operations. ## Primitive specializations Alongside `Stream<T>` there are `IntStream`, `LongStream`, and `DoubleStream` with their own `of`, `range`, etc. Use them for numeric work to avoid boxing and to get numeric terminals like `sum()` and `average()`. ## Why source choice matters All of these sources are **finite and sized** (the stream knows or can compute its element count). A *sized* source lets the framework pre-allocate, split evenly for parallelism, and short-circuit cleanly. This contrasts with the infinite generators (`Stream.generate`, `Stream.iterate`) covered separately, which need a `limit` to terminate.

  • How do you stream the entries of a Map?
    Map has no stream(); call map.entrySet().stream() (or keySet()/values()), since entrySet returns a Set, which is a Collection with stream().
  • What does Stream.of(new int[]{1,2,3}) produce?
    A Stream<int[]> containing exactly one element — the whole array — because int[] is a single Object to varargs. Use Arrays.stream or IntStream.of to stream the ints.

saying these in an interview costs you the question

  • Claiming Map has a stream() method directly (it does not — stream a view).
  • Saying Stream.of(intArray) yields a stream of the ints (it yields Stream<int[]> with one element).
  • Forgetting Arrays.stream has primitive overloads and only ever boxing.
  • Returning null instead of Stream.empty() from a stream-producing method.

context

open as a page

How do Stream.iterate and Stream.generate create infinite streams, and how do you make such a pipeline terminate?

level: middleimportance: must knowfreq 70%

basics

~10 s

Stream.iterate(seed, x -> next) and Stream.generate(supplier) produce endless streams. You must add a short-circuiting operation like limit(n) (or takeWhile/findFirst) so the pipeline stops; otherwise it runs forever.

open as a page

How do you generate a stream of consecutive integers in Java, and what is the difference between IntStream.range and IntStream.rangeClosed?

level: juniorimportance: should knowfreq 58%

basics

~10 s

Use IntStream.range(start, end) for start up to end-1 (end excluded), or IntStream.rangeClosed(start, end) to include end. Both return an IntStream of consecutive ints.

open as a page

How do you create a Stream over the lines of a file with Files.lines, and what resource-management concern does it introduce?

level: seniorimportance: should knowfreq 48%

basics

~10 s

Files.lines(path) returns a Stream<String> of the file's lines, read lazily. It holds an open file handle, so you must close it — wrap it in try-with-resources, since Stream is AutoCloseable.

open as a page

What is a Spliterator, and what role does it play as the underlying source of every Java stream?

level: seniorimportance: should knowfreq 40%

basics

~20 s

A Spliterator is the object that actually feeds a stream: it knows how to traverse elements one by one (tryAdvance) and how to split itself into chunks (trySplit) so a parallel stream can process pieces on different threads.

open as a page