Stream Pipelines

Streams provide a declarative way to process sequences. A pipeline typically has a source, intermediate operations, and a terminal operation.

List<String> names = List.of("Java", "Kotlin", "JavaScript");

List<String> result = names.stream()
    .filter(name -> name.startsWith("J"))
    .map(String::toUpperCase)
    .toList();

Intermediate operations such as filter, map, sorted, and distinct are generally lazy. A terminal operation such as toList, count, findFirst, or forEach drives execution.

Streams are not collections and are usually single-use.

Lazy evaluation

Calling filter() or map() alone does not process elements. A terminal operation drives the pipeline.

Key Takeaways
  • Streams are pipelines, not storage containers.
  • Intermediate operations are generally lazy.
  • A stream should normally be consumed once.