ConceptDifficulty: Advanced1 min

Collecting Into a List, a Set and a Map

A pipeline has to end somewhere, and most of the time the somewhere is a collection. collect is the terminal operation that builds one, and the Collectors class supplies the recipes.

java
List<String> refs   = stream.map(Invoice::reference).toList();
Set<String> unique  = stream.map(Invoice::customer).collect(Collectors.toSet());
Map<String, Long> byCustomer =
        stream.collect(Collectors.groupingBy(Invoice::customer, Collectors.counting()));
The collectors worth knowing by name
CollectorProduces
toList() on the streamAn unmodifiable list, in encounter order
Collectors.toSet()A set, with duplicates gone and no promised order
Collectors.toMap(key, value)A map, throwing if two elements produce one key
Collectors.groupingBy(key)A map from key to a list of the elements with it
Collectors.joining(", ")One string, with a separator

groupingBy is the one that replaces the most code. A second collector inside it says what to do with each group, so counting, summing and collecting to a set are all the same call with a different second argument.

So the end of a pipeline is a choice about shape rather than about work. Decide what you want out, and the collector is usually already written.