# The Stream API — Advanced Java

Source: https://www.geekswithgeeks.com/en/advanced-java/adv-streams

> Build declarative pipelines over collections with filter, map and reduce, collect results with Collectors like groupingBy, and know when parallelStream helps.

## Source, intermediate, terminal

A stream pipeline has a **source** (`collection.stream()`), zero or more **lazy intermediate** ops (`filter`, `map`, `sorted`, `distinct`, `limit`), and one **terminal** op (`collect`, `forEach`, `reduce`, `count`) that triggers execution. Streams don't mutate the source and can't be reused.

## A real pipeline

Collectors build the result: `toList`, `toSet`, `joining`, `groupingBy`, `partitioningBy`, `summingInt`, `averagingDouble`.

```java
Map<Dept, List<String>> byDept = employees.stream()
    .filter(e -> e.salary() > 50_000)
    .sorted(Comparator.comparing(Employee::name))
    .collect(Collectors.groupingBy(
        Employee::dept,
        Collectors.mapping(Employee::name, Collectors.toList())));
```

## parallelStream() with care

`parallelStream()` splits work across the common ForkJoinPool. It only helps for large, CPU-bound, side-effect-free work with a cheap splitter (arrays, `ArrayList`). For small or IO-bound data it's usually slower.
