Java streams (Stream API)
In short: The Stream API (since Java 8) processes data as an “assembly line”: a source such as a list becomes a stream to which you apply steps such as filter, transform and collect. Streams are something different from the I/O streams for files.
In more detail: Instead of loops with intermediate variables you describe what should happen (declarative). A stream stores no data; it is a description of the processing. The work happens only when a terminal operation is called (“lazy”).
In Depth
List<String> names = List.of("Anna", "Ben", "Cem", "Amelie", "Anton");
List<String> result = names.stream() // source
.filter(n -> n.startsWith("A")) // intermediate: select
.map(String::toUpperCase) // intermediate: transform
.sorted() // intermediate: sort
.collect(Collectors.toList()); // terminal: collect
// [AMELIE, ANNA, ANTON]
int sum = IntStream.rangeClosed(1, 100).sum(); // 5050
double avg = names.stream().mapToInt(String::length).average().orElse(0);
Map<Integer, List<String>> byLength = names.stream().collect(Collectors.groupingBy(String::length));Structure of a pipeline: source → intermediate operations (return a stream again) → one terminal operation.
| Kind | Examples |
|---|---|
| Source | list.stream(), Arrays.stream(a), Stream.of(...), IntStream.range(...), Files.lines(path) |
| Intermediate | filter, map, flatMap, sorted, distinct, limit, skip, peek |
| Terminal | collect, forEach, reduce, count, sum, min, max, anyMatch, findFirst, toList() |
- Lazy: Without a terminal operation nothing happens.
limit(3)stops as soon as three hits exist. - Usable once: A stream can be processed only once, afterwards
IllegalStateException. - Original unchanged: Streams do not modify the source. The result is a new collection.
- Parallel:
parallelStream()distributes the work over several cores. Useful only for large amounts and without side effects, otherwise often slower. - Primitive streams:
IntStream,LongStream,DoubleStreamavoid boxing and offersum(),average(). - No side effects: Do not modify outside variables inside
mapandfilter. - Readability: Long chains become unclear. Then move parts into named methods or use a normal loop.
See also: Lambda, Java: lambdas and streams, Iterate