1

I've read that wonderful answer about the difference between map and flatMap.

And there is a picture that demonstrates flatmap:

enter image description here

And quote:

The map is for synchronous, non-blocking, one-to-one transformations while the flatMap is for asynchronous (non-blocking) One-to-Many transformations.

Based on that picture and quote I understand that flatMap allows the creation of more (or fewer) elements than it was in the initial Flux. But all examples I was able to find contains the same amount of element in the initial sequence after flatMap like here:

Flux<Player> players = Flux.just("Zahid Khan", "Arif Khan", "Obaid Sheikh")
    .flatMap(fullname -> Mono
        .just(fullname)
        .map(p -> {
            String[] split = p.split("\\s");
             return new Player(split[0], split[1]);
        })
        .subscribeOn(Scheduler.parallel()));

3 strings as input and 3 players as output:

List<Player> playerList = Arrays.asList(
    new Player("Zahid", "Khan"),
    new Player("Arif", "Khan"), 
    new Player("Obaid", "Sheikh"));

My question is:

Is there a way to modify my example to achieve 3 strings as input and 6 (for example) players as output to prove that flatmap could be one-to-many?

gstackoverflow
  • 36,709
  • 117
  • 359
  • 710
  • The title asks an entirely different question than the body of your question. – Mark Rotteveel Jan 12 '23 at 11:51
  • 1
    @MarkRotteveel: The title sounds good to me. Feel free to edit it. – Nikolas Charalambidis Jan 12 '23 at 12:25
  • @NikolasCharalambidis _"Why many people say that flatmap in reactor is one-to-many?"_ is an entirely different question than _"Is there a way to modify my example to achieve 3 strings as input and 6 (for example) players as output to prove that flatmap could be one-to-many?"_. – Mark Rotteveel Jan 12 '23 at 18:24
  • @Mark Rotteveel To be honest I don't see any contradiction. Feel free to improve the question or title. – gstackoverflow Jan 13 '23 at 13:39

2 Answers2

2

"Many" does not necessarily lead to "more". The term "one-to-many" is often shortened to 1:N where N stands for anything - it can be zero, one, or even ten.

In your example, you flatMap each element into a single one (Mono.just(..) + Mono#map(..)). There can be various numbers of items depending on implementation.

FlatMap as one to zero

The simplest example where flatMap results in no element:

Flux.just("Zahid Khan", "Arif Khan", "Obaid Sheikh")
    .flatMap(fullName -> Mono.empty())
    .subscribe(System.out::println);

FlatMap as one to one

This is exactly your example. I would simplify it a bit:

Flux.just("Zahid Khan", "Arif Khan", "Obaid Sheikh")
    .flatMap(fullName -> {
        String[] split = fullName.split("\\s");
        return Mono.just(new Player(split[0], split[1]));
    })
    .subscribe(System.out::println);
Player(name=Zahid, surname=Khan)
Player(name=Arif, surname=Khan)
Player(name=Obaid, surname=Sheikh)

FlatMap as one to many (more than one)

In this case, we yield 2 players from each input (father and junior):

Flux.just("Zahid Khan", "Arif Khan", "Obaid Sheikh")
    .flatMap(fullName -> {
        String[] split = fullName.split("\\s");
        return Flux.just(
            new Player(split[0], split[1]),
            new Player(split[0], split[1] + " Jr."));
        })
    .subscribe(System.out::println);
Player(name=Zahid, surname=Khan)
Player(name=Zahid, surname=Khan Jr.)
Player(name=Arif, surname=Khan)
Player(name=Arif, surname=Khan Jr.)
Player(name=Obaid, surname=Sheikh)
Player(name=Obaid, surname=Sheikh Jr.)
Nikolas Charalambidis
  • 40,893
  • 16
  • 117
  • 183
  • Thank you! It is exactly that I was looking for. If you have a spare time please take alook https://stackoverflow.com/q/74875058/2674303 – gstackoverflow Jan 12 '23 at 09:18
1

I would like to point one thing:

Difference between .map() and .flatMap() is quite simple:

.map() is meant to map given object to another object (or to the same object, if you want just to change something within that object). This operation is fully synchronous.

.flatMap() is meant to create another Publisher (can either be Mono or Flux) with given object

Emissions from Publisher inside .flatMap() will be "merged" with "main" sequence.

This operation is asynchronous

EDITED: Examples of .flatMap() that returns:

Mono ("one-to-one"):

Flux.just("Hello")
        .flatMap(word -> Mono.just(word + " world!"))  // return Mono that produces another value
        .subscribe(System.out::println);

Which will print the following output:

Hello world!

Flux: ("one-to-many"):

Flux.just("Hello", " world!")
        .flatMap(word -> Flux.fromArray(word.split("(?!^)")))  // return Flux that produces the letters of the given word
        .subscribe(System.out::println);

Which will print the following output:

H
e
l
l
o
 
w
o
r
l
d
!
kerbermeister
  • 2,985
  • 3
  • 11
  • 30
  • Your answer is correct but it doesn't answer ther question – gstackoverflow Jan 12 '23 at 11:14
  • 1
    I thought it does. Since I pointed out that from .flatMap() you can return Publisher that can be either Mono ("one-to-one") or Flux ("one-to-many"). – kerbermeister Jan 12 '23 at 11:16
  • I don't see it) – gstackoverflow Jan 12 '23 at 11:19
  • Your answer is good for https://stackoverflow.com/questions/49115135/map-vs-flatmap-in-reactor – gstackoverflow Jan 12 '23 at 11:20
  • 1
    okay, edited my answer, maybe it helps – kerbermeister Jan 12 '23 at 11:29
  • 2
    @kerbermeister You have missed that you can express one-to-one also with Flux. I also miss the one-to-zero case. Actually, `Mono` yields either zero or one output. `Flux` yields anything between zero to a lot. – Nikolas Charalambidis Jan 12 '23 at 13:37
  • @NikolasCharalambidis It depends on what we mean by "one-to-one" / "one-to-many". Of course, what I mean here is "one object -> publisher that is meant to emit min(0)-max(1) value" / "one object -> publisher that is meant to emit min(0)-max(MAX_LONG) values. So I omit here "zero" cases when we return empty publishers and Flux with only one element, since basically we return Mono or Flux which semantics are described both in your comment and mine. – kerbermeister Jan 12 '23 at 20:05