RxJava uses a chain call design similar to the Stream API , providing filter, map, observeOn and other common operators . Unlike the Builder pattern, which does not require any order of method calls, RxJava’s operator calls need to maintain sequential relationships. A typical chain call scenario is as follows.

1
2
3
4
5
6
Observable
    .create(...)
    .filter(...)
    .map(...)
    .observeOn(...)
    .subscribe(...)

The chain call is triggered from subscribe() and we look at the corresponding source code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public abstract class Observable<T>
    implements ObservableSource<T> {
    ...

    public final void subscribe(Observer<? super T> observer) {
        ...
        try {
            ...
            subscribeActual(observer);
        } catch (NullPointerException e) { // NOPMD
            throw e;
        } catch (Throwable e) {
            ...
        }
    }

    protected abstract void subscribeActual(
        Observer<? super T> observer);
}

You can see that subscribe() actually calls the concrete implementation of subscribeActual(). The subclasses of Observable are ObservableFilter, ObservableMap, ObservableObserveOn, and so on. As you must have thought, these subclasses are obviously related to the corresponding operators. Take filter as an example.

1
2
3
4
5
6
public final Observable<T> filter(Predicate<? super T> predicate) {
  ...
    return RxJavaPlugins.onAssembly(
        new ObservableFilter<T>(this, predicate)
    );
}

As you can see, each filter call wraps the upper-level Observable into a new ObservableFilter, and so on, so that the call stack in our original example actually looks like this:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
// Lastly executed
ObservableObserveOn.subscribeActual() {
    // The third executed
    ObservableMap.subscribeActual() {
        // The second one is executed
        ObservableFilter.subscribeActual() {
            // The most deeply nested ones are executed first
            ObservableCreate.subscribeActual() {
                // DO SOMETHING
            }
        }
    }
}

Here, the principle that RxJava chain calls can still maintain sequential relationships is clear. As for how each Observable is implemented, I won’t expand here, it involves Java’s static proxy, so you can Google it yourself if you are interested.