Zum Hauptinhalt springen

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:

  1. Functional interfaces and lambdas
  2. Intermediate vs terminal, laziness, consumed once
  3. map vs flatMap vs filter
  4. collect, toMap merge, groupingBy
  5. 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/orElseGet are Predicate, Function, Consumer, Supplier.

Streams do nothing until a terminal operation; then they are spent.

Intermediate builds the pipeline. Terminal runs it.

map wraps; flatMap unwraps one level.

Collect into a new collection. Do not forEach into a captured list.

toMap needs 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

  1. Intermediate vs terminal, and why sorted + findFirst still buffers.
  2. map vs flatMap with order lines.
  3. toMap duplicate keys.
  4. Three reasons not to use a stream.
  5. 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-upClear line
Stream is a fast listPipeline; runs at terminal; not reusable
map to a list flattensThat is flatMap
forEach + add is collectSide effect; use collect
Two-arg toMap is safeDuplicate keys throw
.parallel() = faster RESTCommon pool; no transaction

6. Interview drill

Open Collections and streams:

  • Intermediate vs terminal; why lazy?
  • map vs flatMap
  • 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.

Next: Week 8 Day 1 — Threads and Shared Beans