Skip to content
Home » RxJava zip vs merge

RxJava zip vs merge

  • by
RxJava zip vs merge

1. Overview

In this article, we will learn the difference between RxJava zip vs merge.

These two operators work with multiple source Observables to create a single Observable. To learn more about other RxJava topics, refer to these articles.

2. RxJava zip vs merge

RxJava zip operatorRxJava Merge operator
Returns an Observable that applies a function of your choosing to the combination of items emitted, in sequence, by two (or more) other Observables.Combines multiple Observables into one by merging their emissions.
Zip overloaded methods can take up to maximum of 9 observables.Can take multiple observables (as an iterable) and no limit.
Combines the first item emitted by observable #1, observable #2,.., observable #n Similarly, the second item emitted by observable #1, observable #2, and so forth.Does not maintain order
It will only emit as many items as the number of items emitted by the source Observable that emits the fewest items.Emits all items of the provided Observables if no error
Difference between RxJava zip and merge

3. RxJava zip operator

RxJava Zip operator
RxJava Zip operator

The RxJava zip operator combines the emissions of multiple Observables together via a specified function and emits single items for each combination based on the results of the provided function.

The Zip method returns an Observable that applies a function of your choosing to the combination of items emitted, in sequence, by two (or more) other Observables. It can take up to a maximum of 9 observables as input.

The following is the zip overloaded method that takes up to 9 observable sources as input.

public static <T1, T2, T3, T4, T5, T6, T7, T8, T9, R> Observable<R> zip(
            @NonNull ObservableSource<? extends T1> source1, 
            @NonNull ObservableSource<? extends T2> source2, 
            @NonNull ObservableSource<? extends T3> source3,
            @NonNull ObservableSource<? extends T4> source4, 
            @NonNull ObservableSource<? extends T5> source5, 
            @NonNull ObservableSource<? extends T6> source6,
            @NonNull ObservableSource<? extends T7> source7, 
            @NonNull ObservableSource<? extends T8> source8, 
            @NonNull ObservableSource<? extends T9> source9,
            @NonNull Function9<? super T1, ? super T2, ? super T3, ? super T4, ? super T5, ? super T6, ? super T7, ? super T8, ? super T9, ? extends R> zipper) 

The results of the provided function become the items emitted by the returned Observable.

It applies this function in strict sequence, so the first item emitted by the new Observable will result from the function applied to the first item emitted by Observable #1 and the first item emitted by Observable #2.

Similarly, the second item emitted by the new zip-Observable will result from the function applied to the second item emitted by Observable #1 and the second item emitted by Observable #2; and so forth.

It will only emit as many items as the number of items emitted by the source Observable that emits the fewest items.

3.1. RxJava zip functions

As mentioned earlier, the zip takes a function that would combine the items emitted by the source observables.

Based on the overloaded zip method, the type of the function varies. For example, the following zip function takes two observable sources and BiFunction as input.

public static <T1, T2, R> Observable<R> zip(
            @NonNull ObservableSource<? extends T1> source1, @NonNull ObservableSource<? extends T2> source2,
            @NonNull BiFunction<? super T1, ? super T2, ? extends R> zipper) 

// takes BiFunction as input function

The following zip overloaded function that takes three observables and Function3 as input.

public static <T1, T2, T3, R> Observable<R> zip(
            @NonNull ObservableSource<? extends T1> source1, @NonNull ObservableSource<? extends T2> source2,
            @NonNull ObservableSource<? extends T3> source3,
            @NonNull Function3<? super T1, ? super T2, ? super T3, ? extends R> zipper) 

3.2. RxJava Zip Example

Let’s see RxJava Zip examples to understand the above concepts.

The following test case contains two source observables observableOne and observableTwo. The zipper BiFunction takes the items emitted by source observables and combines them i.e., this function takes the first item emitted by observableOne and observableTwo as input and emits the first item of new Observable.

Similarly, the second item emitted by the new zip-Observable will result from the function applied to the second item emitted by observableOne and observableTwo; and so forth.

@Test
public void testZipOperator() {
        Observable<String> observableOne = Observable.just("Hello", "World");
        Observable<String> observableTwo = Observable.just("Bye", "Friends");
        BiFunction<String, String, String> zipper = new BiFunction<String, String, String>() {

            @Override
            public String apply(String s, String s2) {
                return s + "|" + s2;
            }
        };
        Observable<String> resultObservable = Observable.zip(observableOne, observableTwo, zipper);

        resultObservable.subscribe(item -> System.out.println("Emitted item : " + item),
                error -> error.printStackTrace(),
                () -> System.out.println("Done"));

}

If you execute the above test case, it produces the following output.

Emitted item : Hello|Bye
Emitted item : World|Friends
Done

Let’s take another zip example with varying sizes. It will only emit as many items as the number of items emitted by the source Observable that emits the fewest items.

The following observableTwo contains fewer items than the observableOne. So the resultant Observable emits only as many items as in observableTwo.

@Test
    public void testZipOperator() {
        Observable<String> observableOne = Observable.just("1", "2", "3", "4", "5", "6");
        Observable<String> observableTwo = Observable.just("A", "B");
        BiFunction<String, String, String> zipper = new BiFunction<String, String, String>() {

            @Override
            public String apply(String s, String s2) {
                return s + "|" + s2;
            }
        };
        Observable<String> resultObservable = Observable.zip(observableOne, observableTwo, zipper);

        resultObservable.subscribe(item -> System.out.println("Emitted item : " + item),
                error -> error.printStackTrace(),
                () -> System.out.println("Done"));

    }

Since observableTwo contains fewer items (2), the above code emits only two items as output:

Emitted item : 1|A
Emitted item : 2|B
Done

4. RxJava Merge operator

RxJava Merge operator

RxJava Merge operator combines multiple Observables into one by merging their emissions.

It combines the output of multiple Observables so that they act like a single Observable.

Merge will not maintain the order while emitting the items. For example, the following test case merges the observableOne and observableTwo but does not maintain the order.

@Test
    public void testMergeOperator() {
        Observable<Integer> observableOne = Observable.range(0, 10).delay(1, TimeUnit.MILLISECONDS);
        Observable<Integer> observableTwo = Observable.range(1111, 10);

        Observable<Integer> resultObservable = Observable.merge(observableOne, observableTwo);

        resultObservable
                .subscribe(item -> System.out.println("Emitted item : " + item),
                error -> error.printStackTrace(),
                () -> System.out.println("Done"));

    }

For single-element static streams, you won’t see any real difference. However, in complex use cases, the order will not be guaranteed.

You can notice in the below output that the Merge operator does not maintain the order.

Emitted item : 3
Emitted item : 1111
Emitted item : 1112
Emitted item : 1113
Emitted item : 1114
Emitted item : 1115
Emitted item : 1116
Emitted item : 1117
Emitted item : 1118
Emitted item : 1119
Emitted item : 1120
Emitted item : 0
Emitted item : 1
Emitted item : 2

5. Conclusion

To sum up, we have learned the difference between the RxJava zip and merge operators. You can find code samples in our GitHub repository.

Leave a Reply

Your email address will not be published. Required fields are marked *