Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java streams interview: laziness, one-use pipelines and reduction rules

Last updated: 29 Sept 20264 min read
tutorial
IntermediateBy AITrove Editorial

A stream describes a one-use computation pipeline; intermediate operations are evaluated as required by a terminal operation.

Java 8+. This is a complete program using JDK classes.

When does the work run?

Creating this map-and-filter pipeline does not traverse the source. collect supplies the terminal demand. The inspection counter is a teaching trace for this particular collection operation; production behavior must not rely on side effects in intermediate operations.

A terminal operation is allowed to avoid work it does not need. For example, an implementation can compute a count from known source sizing without executing a mapping function that does not affect that count. A trace for collect is not a guarantee that every terminal will visit the same callbacks.

Can the stream be reused?

No. Build a fresh stream from its source for another terminal operation. Keeping a Stream field in a repository and handing it to several consumers creates a lifecycle failure, even when the underlying collection itself is reusable.

What makes a parallel reduction correct?

The identity must be neutral for the combining operation, and the accumulation must be associative under the required result semantics. Integer overflow, floating-point rounding and a non-neutral seed can change results when partitions are combined. Parallelism also does not make captured mutable state safe.

Encounter order and execution order differ. A terminal result can preserve encounter order while workers execute callbacks in another order. Use an explicit ordering requirement rather than a print statement to infer what a parallel pipeline guarantees.

Working program

Java
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.*;
public class StreamDemandProbe {
    public static void main(String[] args){
        AtomicInteger inspected=new AtomicInteger();
        Stream<Integer> selected=Arrays.asList(3,7,7).stream()
            .map(quantity->{inspected.incrementAndGet();return quantity;}).filter(quantity->quantity>4);
        System.out.println(inspected.get());
        System.out.println(selected.collect(Collectors.toList()));
        System.out.println(inspected.get());
        try{selected.count();}catch(IllegalStateException consumed){System.out.println("Stream already consumed");}
    }
}

Output

Output
0
[7, 7]
3
Stream already consumed

Costs and boundaries

This terminal traversal performs O(n) work and stores O(k) selected values. The atomic counter is instrumentation, not a recommendation for side-effect-driven stream design. Parallel execution adds splitting, scheduling and combining costs; no speedup is measured here.

Common Mistakes

  • Do not depend on peek or map side effects for required business work.
  • A stream is not a reusable collection.
  • A non-neutral reduction identity can be applied once per partition.

Read next

Pipeline contracts, Captured state.

java
streams-interview
Storage details