Java Streams Quiz: Collectors, Optional and Reduce Test
Practise Java streams with 15 questions and three programs on lazy pipelines, map and flatMap, reduce, groupingBy and toMap, Optional, IntStream and parallel.
- Course: Java study plan
- Module: Streams
- Kind: Checkpoint — cleared at 70%
- Reading time: 30 min
- Runtime: OpenJDK 18
Checkpoint — Streams is the checkpoint that closes the Streams module: a graded quiz and whole-program exercises, passed at 70%.
Instructions
This checkpoint covers the stream model (sources, lazy intermediates, one terminal), every intermediate operation including flatMap, sorted, distinct, limit/skip and takeWhile, the terminals with the three forms of reduce, the collectors — toMap, joining, groupingBy with downstreams, partitioningBy, teeing — Optional as a return type, the primitive streams, and parallel execution with its rules.
How it works. Fifteen questions and three programs; 70% on the questions and every program accepted clears the module.
Before you start, make sure you can answer:
- Why a pipeline with no terminal does nothing, and why a stream cannot be reused.
- When
mapis wrong andflatMapis right. - What the one-argument
reducereturns, and what a wrong identity does in parallel. - How
toMapfails on duplicate keys, and how to fix it. - The shape of
groupingBy(classifier, mapFactory, downstream). orElseversusorElseGet; whereOptionaldoes not belong.- Why
Stream<Integer>is slower thanIntStream, and whatsum()of an empty stream is. - The four things a lambda must not do inside a parallel pipeline.
The programs are a sales report built from groupingBy and teeing, a text analyser over chars() and flatMap, and a scheduler that finds the first free slot with takeWhile, IntStream and Optional.
Common questions
Why does a Java stream pipeline with no terminal operation do nothing?
Intermediate operations are lazy: they only record the computation, and elements are pulled through only when a terminal operation such as toList, count or forEach runs. The terminal also consumes the stream, which is why a stream cannot be reused.
What does the one-argument reduce return?
An Optional, because an empty stream has nothing to fold. The two-argument form, reduce(identity, accumulator), returns a plain value — and in parallel a wrong identity is applied once per chunk, giving wrong results.
What is the shape of groupingBy(classifier, mapFactory, downstream)?
The classifier computes each element's key, the map factory chooses the map type — TreeMap::new for sorted keys — and the downstream collector reduces each group, for example counting() or mapping(Person::name, toList()). With only a classifier, each group is a List.
Exercises
Sales report
Read an integer n and n lines region product qty price (integers for qty and price). Revenue of a line is qty × price. Using collectors, print for every region in natural order:
<region>: revenue=<total revenue> items=<total qty> top=<product with the highest revenue in the region; ties by product name>
Then one line range=<region with the lowest total revenue>..<region with the highest> (ties by region name, alphabetically first), computed with teeing over the per-region totals.
Example: 4 then east pen 10 2, east ink 1 30, west pen 5 2, east pad 3 10 →
east: revenue=80 items=14 top=ink
west: revenue=10 items=5 top=pen
range=west..eastText analyser
Read all of standard input (several lines). Words are separated by whitespace; compare them case-insensitively. Print:
lines=<non-blank lines> words=<total words>unique=<distinct lower-cased words>longest=<the first longest word as written in the input>common=<the three most frequent lower-cased words as word:count, most frequent first, ties by word, joined by ,>(fewer if there are fewer words)letters=<the total number of letters across all words, via chars()>
Build the word stream with lines().flatMap(...).
Example input
the cat sat
the mat
The end
→
lines=3 words=7
unique=5
longest=the
common=the:3,cat:1,end:1
letters=21First free slot
A day has hours 0..23. Read an integer n and n bookings start end (a booking occupies hours start to end − 1), then a duration d. Print:
busy=<number of distinct booked hours>— flatten each booking to its hours withflatMap/IntStream.range, thendistinct.slot=<h>-<h+d>for the earliest starth(0 ≤ h ≤ 24 − d) such that no booking overlaps[h, h + d)— anIntStreamover candidate starts,filterwithnoneMatchover the bookings,findFirst; orslot=none.free=<hours from 0 up to the first booked hour>usingtakeWhileoverIntStream.range(0, 24).
Example: 2 then 9 12, 13 15, then 3 →
busy=5
slot=0-3
free=9In this module: Streams
- Streams — pipelines over data
- Intermediate operations — map, filter, flatMap and friends
- Terminal operations — reduce, match, find, count
- Collectors — toMap, joining, groupingBy, partitioningBy
- Optional — a return type, not a null replacement
- Primitive streams — IntStream, LongStream, DoubleStream
- Parallel streams, ordering and performance
- Checkpoint — Streams (this lesson)
← Parallel streams, ordering and performance · Stack and heap — where every value lives →