is new request
๐ Reactive Programming in Java (Project Reactor) โ All-in-One Guide
This guide includes:
- โ Cheat Sheet of Common Transformations
- ๐ Step-by-Step Stream Flow Diagram
- ๐งช Practice Problems with Hints
โ 1. Cheat Sheet: Common Reactive Transformationsโ
| Problem | Operator(s) to Use | Resulting Type |
|---|---|---|
| List<T> โ Flux<T> | Flux.fromIterable(list) | Flux<T> |
| Flux<T> โ List<T> | collectList() | Mono<List<T>> |
| Flux<T> โ Map<K, T> | collectMap(keyFn, valFn) | Mono<Map<K, T>> |
| Flux<T> โ Map<K, List<T> > | collectMultimap(keyFn) | Mono<Map<K, List<T>>> |
| Transform each item | map() | Flux<R> |
| Transform and flatten (async calls) | flatMap() | Flux<R> |
| Async calls in order | concatMap() | Flux<R> |
| Group by key | groupBy() | GroupedFlux<K, T> |
| Fallback value | switchIfEmpty(Mono.just(...)) | Flux<T> or Mono<T> |
| Combine two Flux<T> | zipWith(otherFlux) | Flux<Tuple2<T1, T2>> |
| Run after completion | doOnTerminate() | Same as input stream |
| Parallel processing | parallel().runOn(Schedulers.parallel()) | ParallelFlux<T> |
๐ 2. Stream Flow Diagram (Example: Group + Transform + Return)โ
Problem:โ
You have a Flux<MyObject>, and you want to:
- Group by
documentType - For each group, process to get a
DocStatusModel - Collect all into a
List<DocStatusModel>
Flow Diagram:โ
[Flux<MyObject>]
โ
โโ> collectMultimap(MyObject::getDocumentType)
โ โ Mono<Map<DocumentType, List<MyObject>>>
โ
โโ> flatMapMany(map -> Flux.fromIterable(map.entrySet()))
โ โ Flux<Map.Entry<DocumentType, List<MyObject>>>
โ
โโ> map(entry -> process(entry.getKey(), entry.getValue()))
โ โ Flux<DocStatusModel>
โ
โโ> collectList()
โ Mono<List<DocStatusModel>>
Each transformation stage is composable, testable, and reactive.
๐งช 3. Practice Problems with Hintsโ
๐น Problem 1: Group Books by Genreโ
Input: Flux<Book>, where Book has a getGenre() method
Goal: Mono<Map<String, List<Book>>> grouped by genre
Hint:
Use collectMultimap(Book::getGenre)
๐น Problem 2: Convert Orders to EnrichedOrders (with async call)โ
Input: Flux<Order>
Goal: Flux<EnrichedOrder>
Hint:
.flatMap(order -> enrichOrderAsync(order))
๐น Problem 3: Provide Default When Emptyโ
Input: Flux<Item>
Goal: Emit default items if source is empty
Hint:
.switchIfEmpty(Flux.just(defaultItem1, defaultItem2))
๐น Problem 4: Retry on Errorโ
Input: Flux<Data> with flaky source
Goal: Retry 3 times before failing
Hint:
.retry(3)
๐น Problem 5: Combine Two Streamsโ
Input: Flux<User>, Flux<Account>
Goal: Flux<UserAccountSummary>
Hint:
userFlux.zipWith(accountFlux, (user, account) -> new UserAccountSummary(user, account))
๐ฌ Tip for Masteryโ
- Practice in a sandbox using
main()or unit tests - Break problems into: Input โ Transform โ Output
- Think in data shapes (e.g. Flux<T> , Mono<List<T> >, Map<K, V>)
Happy streaming! ๐ก