Skip to main content

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โ€‹

ProblemOperator(s) to UseResulting 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 itemmap()Flux<R>
Transform and flatten (async calls)flatMap()Flux<R>
Async calls in orderconcatMap()Flux<R>
Group by keygroupBy()GroupedFlux<K, T>
Fallback valueswitchIfEmpty(Mono.just(...))Flux<T> or Mono<T>
Combine two Flux<T>zipWith(otherFlux)Flux<Tuple2<T1, T2>>
Run after completiondoOnTerminate()Same as input stream
Parallel processingparallel().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! ๐Ÿ’ก