Week 7 Review — Streams
Goal
This review checks whether I can describe a pipeline, flatten one level, collect without side effects, and refuse .parallel() on a transactional service.
Week 7 topics:
- Functional interfaces and lambdas
- Intermediate vs terminal, laziness, consumed once
mapvsflatMapvsfiltercollect,toMapmerge,groupingBy- When not to use streams, parallel + Spring
1. Week 7 big picture
orders.stream() source (not a new list)
.filter(Order::isOpen) Predicate, lazy
.flatMap(o -> o.lines().stream()) unwrap one level
.map(Line::sku) Function
.distinct()
.collect(Collectors.toSet()) terminal — now it runs, stream is spent
do not: forEach(list::add)
do not: parallel() inside @Transactional
do not: map(order -> order.lines()) // Stream<List<Line>>
2. Core memory sentences
A lambda is an instance of a one-method interface.
filter/map/forEach/orElseGetare Predicate, Function, Consumer, Supplier.
Streams do nothing until a terminal operation; then they are spent.
Intermediate builds the pipeline. Terminal runs it.
mapwraps;flatMapunwraps one level.
Collect into a new collection. Do not
forEachinto a captured list.
toMapneeds a merge function if keys can collide.
Streams declare a transformation. Loops stay better for control flow and side effects.
parallel()is not a free speedup, and it does not carry the Spring transaction.
3. Speak these without notes
- Intermediate vs terminal, and why
sorted+findFirststill buffers. mapvsflatMapwith order lines.toMapduplicate keys.- Three reasons not to use a stream.
- Why
@Transactional+parallel()breaks JPA.
4. Tiny code proofs
Proof A — spent stream
Call toList() twice on the same stream(). Confirm IllegalStateException.
Proof B — lazy short-circuit
map that prints, then findFirst. Confirm one print. Add sorted() before findFirst and confirm many prints.
Proof C — map vs flatMap
map(Order::lines) vs flatMap(o -> o.lines().stream()). Print the resulting element types (list vs line).
5. Common mix-ups from this week
| Mix-up | Clear line |
|---|---|
| Stream is a fast list | Pipeline; runs at terminal; not reusable |
map to a list flattens | That is flatMap |
forEach + add is collect | Side effect; use collect |
Two-arg toMap is safe | Duplicate keys throw |
.parallel() = faster REST | Common pool; no transaction |
6. Interview drill
Open Collections and streams:
- Intermediate vs terminal; why lazy?
mapvsflatMap- When should you not use streams?
groupingBy,toMap, and key collisions
7. Ready for Week 8?
I am ready if I can say “spent after terminal,” flatten lines with flatMap, and refuse parallel streams inside a transaction.
Week 8 is concurrency: threads, synchronized, volatile, executors, and why @Async cares which thread you are on.