Java OO & Functional/Tổng kết module — Stream API & Lambda
38/38
Bài 38 / 38~10 phútStream API & LambdaMiễ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 caoflatMap, distinct, sorted, takeWhile/dropWhile, peek
  6. Optional — NPE-safe chaining, map/flatMap/orElse/orElseThrow
  7. Collectors deepgroupingBy, 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>
Intermediate statefulsorted, distinct, skipStream<T>Có (buffer)
Intermediate short-circuitlimit(n), takeWhileStream<T>
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()
ArrayArrays.stream(arr)
FactoryStream.of(a, b, c), Stream.empty()
Int rangeIntStream.range(0, n), IntStream.rangeClosed(1, n)
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 basicsParallel Stream):

  • Quên terminal opstream.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 lambdaforEach(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/OparallelStream() 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?

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

Chưa có câu hỏi

Đặt câu hỏi

Có gì chưa rõ trong bài? Đặt câu hỏi đầu tiên — câu trả lời từ cộng đồng giúp bạn (và người sau).

Đặt câu hỏi đầu tiên