What is the difference between concatMap and flatMap in RxJava


As you wrote, the two functions are very similar and the subtle difference is how the output is created ( after the mapping function is applied).

Flat map uses merge operator while concatMap uses concat operator.

As you see the concatMap output sequence is ordered - all of the items emitted by the first Observable being emitted before any of the items emitted by the second Observable,
while flatMap output sequence is merged - the items emitted by the merged Observable may appear in any order, regardless of which source Observable they came from.


Even though the answers here are good it wasn't easy to spot the difference without an example. So, I created a simple example for this:

@Test
public void flatMapVsConcatMap() throws Exception {
    System.out.println("******** Using flatMap() *********");
    Observable.range(1, 15)
            .flatMap(item -> Observable.just(item).delay(1, TimeUnit.MILLISECONDS))
            .subscribe(x -> System.out.print(x + " "));

    Thread.sleep(100);

    System.out.println("\n******** Using concatMap() *********");
    Observable.range(1, 15)
            .concatMap(item -> Observable.just(item).delay(1, TimeUnit.MILLISECONDS))
            .subscribe(x -> System.out.print(x + " "));

    Thread.sleep(100);
}

******** Using flatMap() *********

1 2 3 4 5 6 7 9 8 11 13 15 10 12 14

******** Using concatMap() *********

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15

As it could be seen from the output, the results for flatMap are unordered while for concatMap they're.


One very important difference: the concatMap waits for the current emitted observable to complete and flatMap doesn't. flatMap tries to start as many possible. Simply said - you cannot concatenate something infinite. Just make sure that the observables you emit in concatMap can complete, otherwise the whole flow will get stuck waiting for the current observable to complete to concatenate the next one.