Lists, sets, strings and numbers
A collector is a recipe that tells stream.collect(...) how to build a result: a list, a set, a joined string, a map, or a map of groups with counts and totals. Collectors provides ready-made ones like toMap, groupingBy, partitioningBy, joining and teeing, and they can be nested to answer questions like "total sales per city" in one pipeline.
Change the code and press Run (Ctrl+Enter). Try to predict the output first, then break it on purpose and read the error. Your edits are saved and match the lesson page.
Practice questions
Write the code in the editor, run it, then open the model answer to compare.
Given words "apple", "bat", "cherry", "dog", "egg", group them by length into a TreeMap and print it.
Count how many times each character appears in "banana" and print the result as a TreeMap<Character, Long>.
From a list of (name, dept, salary) employees, print the highest-paid employee's name per department, using groupingBy with collectingAndThen and maxBy.
Explain it without notes
What are the components of a Collector, and what does each do?
How does toMap behave with duplicate keys and null values, and how do you control it?
Explain groupingBy with a downstream collector, using an example.
What is the difference between filtering before groupingBy and using Collectors.filtering as a downstream?
When would you use partitioningBy, collectingAndThen and teeing?
Expected output
toList: [mango, apple, kiwi, apple, banana]
toCollection: [apple, banana, kiwi, mango]
joining: mango, apple, kiwi, banana
joining + affixes: [mango | apple | kiwi | banana]
unmodifiable: [MANGO, APPLE, KIWI, APPLE, BANANA]
counting: 5
averaging length: 5.0
summarizing: IntSummaryStatistics{count=5, sum=25, min=4, average=5.000000, max=6}