Concat VS Merge operator

paul :

I was checking the documentation of RXJava and I notice that concat and merge operators seems do the same. I wrote a couple test to be sure.

@Test
public void testContact() {

    Observable.concat(Observable.just("Hello"),
                      Observable.just("reactive"),
                      Observable.just("world"))
              .subscribe(System.out::println);
}

@Test
public void testMerge() {

    Observable.merge(Observable.just("Hello"),
                      Observable.just("reactive"),
                      Observable.just("world"))
            .subscribe(System.out::println);
}

The documentation says

The Merge operator is also similar. It combines the emissions of two or more Observables, but may interleave them, whereas Concat never interleaves the emissions from multiple Observables.

But still I don't full understand, running this test thousand of times the merge result always is the same. Since the order is not granted I was expecting sometimes "reactive" "world" "hello" for example.

The code is here https://github.com/politrons/reactive

Artur Biesiadowski :

It is as described in documentation you have quoted - merge can interleave the outputs, while concat will first wait for earlier streams to finish before processing later streams. In your case, with single-element, static streams, it is not making any real difference (but in theory, merge could output words in random order and still be valid according to spec). If you want to see the difference, try following (you will need to add some sleep afterwards to avoid early exit)

    Observable.merge(
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "A" + id),
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "B" + id))
    .subscribe(System.out::println);

A0 B0 A1 B1 B2 A2 B3 A3 B4 A4

versus

    Observable.concat(
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "A" + id),
            Observable.interval(1, TimeUnit.SECONDS).map(id -> "B" + id))
    .subscribe(System.out::println);

A0 A1 A2 A3 A4 A5 A6 A7 A8

Concat will never start printing B, because stream A never finishes.

s/stream/observable/g ;)

Documentation gives nice graphs to show the difference. You need to remember that merge gives no guarantee of interleaving items one by one, it is just an one of possible examples.

Concat

Concat operator Merge

Merge operator

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=424812&siteId=1