RxJava Zip Operator

Authors
  • Amit Shekhar
    Name
    Amit Shekhar
    Published on
RxJava Zip Operator

I am Amit Shekhar, I have taught and mentored many developers, and their efforts landed them high-paying tech jobs, helped many tech companies in solving their unique problems, and created many open-source libraries being used by top companies. I am passionate about sharing knowledge through open-source, blogs, and videos.

Join my program and get high paying tech job: amitshekhar.me

Before we start, I would like to mention that, I have released a video playlist to help you crack the Android Interview: Check out Android Interview Questions and Answers.

In this blog, we will learn the RxJava Zip Operator with an example.

As per the RxJava official documentation,

Zip combine the emissions of multiple Observables together via a specified function and emit single items for each combination based on the results of this function.

zip operator rxjava marble diagram

Zip operator allows us to get the results from multiple observables at a time.

Suppose that we have two network observables as follows:

  • CricketFansObservable - A network observable which returns the list of users who are cricket fans.
  • FootballFansObservable - A network observable which returns the list of users who are football fans.

CricketFansObservable as below:

fun getCricketFansObservable(): Observable<List<User>> {
    return networkService.getCricketFansObservable()
}

FootballFansObservable as below:

fun getFootballFansObservable(): Observable<List<User>> {
    return networkService.getFootballFansObservable()
}

And our NetworkService as below:

class NetworkService {

    fun getCricketFansObservable(): Observable<List<User>> {
        return Observable.create<List<User>> { emitter ->
            if (!emitter.isDisposed) {
                // fetch data from network
                val data = fetchUserListFromNetwork()
                emitter.onNext(data)
                emitter.onComplete()
            }
        }.subscribeOn(Schedulers.io())
    }

    fun getFootballFansObservable(): Observable<List<User>> {
        return Observable.create<List<User>> { emitter ->
            if (!emitter.isDisposed) {
                // fetch data from network
                val data = fetchUserListFromNetwork()
                emitter.onNext(data)
                emitter.onComplete()
            }
        }.subscribeOn(Schedulers.io())
    }

    private fun fetchUserListFromNetwork(): List<User> {
        return listOf()
    }

}

An Observer as below:

private fun getObserver(): Observer<List<User>> {
    return object : Observer<List<User>> {
        override fun onSubscribe(d: Disposable) {
            println("onSubscribe")
        }

        override fun onNext(userList: List<User>) {
            println("onNext : $userList")
        }

        override fun onError(e: Throwable) {
            println("onError : ${e.message}")
        }

        override fun onComplete() {
            println("onComplete")
        }
    }
}

A utility function to filter the user who loves both

private fun filterUserWhoLovesBoth(cricketFans: List<User>,
                                   footballFans: List<User>): List<User> {
    val userWhoLovesBoth = ArrayList<User>()
    for (footballFan in footballFans) {
        if (cricketFans.contains(footballFan)) {
            userWhoLovesBoth.add(footballFan)
        }
    }
    return userWhoLovesBoth
}

Let's connect all together to understand zip operator.

Observable.zip(
    getCricketFansObservable(),
    getFootballFansObservable(),
    BiFunction<List<User>, List<User>, List<User>> { cricketFans, footballFans ->
        // here we get both the results at a time.
        return@BiFunction filterUserWhoLovesBoth(cricketFans, footballFans)
    })
    .subscribeOn(Schedulers.io())
    .observeOn(AndroidSchedulers.mainThread())
    .subscribe(getObserver())

First, we are making two network calls(in parallel as we are using Zip Operator), then after getting the results, we are filtering the users who love both.

By zipping two observables using the RxJava Zip operator, both the network calls run in parallel. And we get the result of both the observables when both finish. In this way, we get the results of both the observables at a time.

Advantages of Zip Operator:

  • Run all the tasks in parallel when Schedulers are correctly provided to each observable.
  • Return the results of all the tasks in a single callback when all the tasks are completed.

This way we can use RxJava Zip Operator to solve the interesting problem.

Find the complete project here and learn RxJava.

Prepare yourself for Android Interview: Android Interview Questions

That's it for now.

Thanks

Amit Shekhar

You can connect with me on:

Read all of my high-quality blogs here.