Java OO & Functional
38/38
Bài 38 / 38~10 phútStream API & LambdaLộ trình · chặng 06/21Miễn phí… lượt xem

Tổng kết module — Stream API & Lambda

Recap toàn module: cheat-sheet, glossary, pitfall checklist, và self-assessment 1-1 với 5 learning outcomes. Dùng để ôn trước khi chuyển module tiếp theo.

TL;DR: Module Stream API & Lambda dạy cách xử lý dữ liệu theo functional style trong Java — từ lambda & method reference (building block), stream pipeline lazy (cơ chế cốt lõi), collectors & optional (terminal nâng cao), đến parallel stream & immutability (production concerns). Bài này là recap + self-assessment để kiểm tra xem bạn thực sự nắm trước khi tiếp tục.

Hành trình qua module

Bạn vừa đi qua 10 bài concept + mini-challenge:

  1. Lambda & Functional Interface — SAM type, @FunctionalInterface, 4 built-in cốt lõi (Predicate, Function, Consumer, Supplier)
  2. Method Reference & invokedynamic — 4 loại method ref, cơ chế invokedynamic bytecode, tại sao không slower than lambda
  3. Stream basics — lazy pipeline, intermediate vs terminal, element-by-element, short-circuit
  4. map / filter / reduce — 3 op cốt lõi, reduce nontrivial, chaining
  5. Stream nâng cao — flatMap, distinct, sorted, takeWhile/dropWhile, peek
  6. Optional — NPE-safe chaining, map/flatMap/orElse/orElseThrow
  7. Collectors deep — groupingBy, partitioningBy, joining, downstream collector, custom Collector
  8. Parallel Stream — ForkJoinPool, khi nào parallel win/lose, thread-safety, Spliterator
  9. Immutability & Functional Style — value object, pure function, compose pipeline
  10. Mini-challenge Sales Report — tổng hợp toàn bộ

Cheat-sheet

Phân loại operation

LoạiVí dụReturn typeLazy?
Intermediate statelessfilter, map, flatMap, peekStream<T>Có
Intermediate statefulsorted, distinct, skipStream<T>Có (buffer)
Intermediate short-circuitlimit(n), takeWhileStream<T>Có
Terminal eagercollect, forEach, reduce, count, toListnon-StreamKhông
Terminal short-circuitfindFirst, findAny, anyMatch, allMatch, noneMatchnon-StreamKhông

Nguồn stream thường dùng

NguồnCách tạoHữu hạn?
Collectionlist.stream()Có
ArrayArrays.stream(arr)Có
FactoryStream.of(a, b, c), Stream.empty()Có
Int rangeIntStream.range(0, n), IntStream.rangeClosed(1, n)Có
Infinite generatorStream.iterate(seed, fn), Stream.generate(supplier)Không — cần limit
FileFiles.lines(path) trong try-with-resourcesCó (EOF)

Functional interface mapping

InterfaceMethodDùng trong
Predicate<T>boolean test(T t)filter, anyMatch, noneMatch
Function<T,R>R apply(T t)map, flatMap
Consumer<T>void accept(T t)forEach, peek
Supplier<T>T get()Stream.generate, orElseGet
UnaryOperator<T>T apply(T t)Stream.iterate
BinaryOperator<T>T apply(T t1, T t2)reduce
Comparator<T>int compare(T a, T b)sorted, min, max

Glossary

Thuật ngữĐịnh nghĩa ngắn
Lazy evaluationIntermediate op không chạy cho đến khi có terminal op kích hoạt
PipelineChuỗi op xâu chuỗi nhau: stream().op1().op2()...terminal()
Short-circuitOp dừng sớm khi đủ kết quả — không duyệt hết stream
Stateful intermediateOp phải buffer trước khi emit (sorted, distinct)
SinkInterface nội bộ JDK nhận element từ upstream stage; terminal op wires các Sink thành chuỗi khi pipeline khởi động
Loop FusionJDK gộp nhiều intermediate op thành 1 lượt duyệt qua Sink chain
SpliteratorInterface bên dưới Stream để traverse source; hỗ trợ split cho parallel
OptionalContainer 0-hoặc-1 giá trị, tránh NPE khi return
CollectorRecipe cho terminal op collect() — cách gom element thành kết quả
ForkJoinPoolThread pool dùng cho parallelStream() — work-stealing
Pure functionKhông side-effect, output chỉ phụ thuộc input — safe cho stream

Pitfall checklist

Trước khi merge code dùng Stream, kiểm tra từng mục này (xem chi tiết tại Stream basics và Parallel Stream):

  • Quên terminal op — stream.filter(...) không có .toList() hay .forEach(...) → không chạy gì
  • Reuse stream — dùng stream sau khi đã có terminal op → IllegalStateException
  • sorted() trên infinite stream — hang forever; dùng limit TRƯỚC sorted
  • peek cho logic chính — Java 9+ có thể skip peek trên stream SIZED; dùng forEach
  • Modify collection gốc trong lambda — forEach(x -> list.add(...)) → ConcurrentModificationException
  • limit TRƯỚC sorted — thứ tự op ảnh hưởng kết quả; limit(3).sorted() khác sorted().limit(3)
  • parallel với stateful lambda — chia sẻ mutable state giữa thread → race condition
  • parallel với I/O — parallelStream() dùng ForkJoinPool common; blocking I/O chặn pool
  • NPE từ Optional.get() — dùng orElseThrow() hoặc isPresent() check trước

✅ Self-assessment

Bạn đã đạt module này nếu trả lời được 5 câu sau (match 1-1 với learning outcomes):

  • Explain được cơ chế lazy evaluation — tại sao intermediate op chỉ ghi ý định và terminal op mới kích hoạt pipeline, và hệ quả với stream vô hạn và short-circuit
  • Implement được stream pipeline với filter/map/reduce/collect trên collection lẫn infinite source — không cần nhìn tài liệu
  • Choose được đúng functional interface (Predicate, Function, Consumer, Supplier) và viết method reference tương ứng cho từng stream op
  • Diagnose được pitfall stream phổ biến: missing terminal op, stream reuse IllegalStateException, stateful op trên infinite stream
  • Compare được imperative loop vs functional stream về readability, memory, và short-circuit behaviour

Module tiếp theo: khi bạn tick được cả 5 ô trên, bạn sẵn sàng cho Java Internals — JVM memory model, GC, concurrency, và performance tuning.

Bài này có giúp bạn hiểu bản chất không?

Bài này đáng gửi cho bạn học cùng?

Copy link đã gắn nguồn — dán group, chat, hoặc LinkedIn.

Lộ trình Junior Java Backend Developer

✓ Bạn vừa đi hết chặng Lambda & Stream API (6/21)

Chặng tiếp: Maven / Gradle — build & dependency management — “Starter & BOM: Quản Lý Dependency Đồng Bộ Trong Maven”

Thảo luận & góp ý

Hỏi đáp về bài này