1. 程式人生 > >RxJava 系列之變換操作符flatmap(2)

RxJava 系列之變換操作符flatmap(2)

上一篇文章中我們介紹了map操作符,其實還是比較簡單的,本文將介紹稍微複雜一點的操作符flatmap。

怎麼使用?

比如我們現在有這樣一個需求,我們現在有一個Person的集合,每一個Person裡面都有多個收貨地址Address,現在我們想打印出收貨地址。第一種實現方式

private void test5() {
      List<Person> persons = new ArrayList<>();
        List<Address> zhangsanAddress = new ArrayList<>();
        zhangsanAddress.add(new
Address("北京")); zhangsanAddress.add(new Address("上海")); zhangsanAddress.add(new Address("深圳")); final Person person = new Person("zhangsan", zhangsanAddress); List<Address> lisiAddress = new ArrayList<>(); lisiAddress.add(new Address("合肥")); lisiAddress.add(new
Address("杭州")); lisiAddress.add(new Address("廣州")); Person person2 = new Person("lisi", lisiAddress); persons.add(person); persons.add(person2); Observable.from(persons).subscribe(new Subscriber<Person>() { @Override public void
onCompleted() { } @Override public void onError(Throwable e) { } @Override public void onNext(Person person) { for (Address address : person.getAddresses()) { Log.e(TAG, "onNext: person = " + person.getName() + "---address = " + address.getAddressName()); } } }); }

雖然看起來還是挺簡單的,但是我們現在不想在onNext方法裡面寫for迴圈,而是希望 Subscriber 中直接傳入單個的 Address 物件呢?用 map() 顯然是不行的,因為 map() 是一對一的轉化,而我現在的要求是一對多的轉化。那怎麼才能把一個 Person 轉化成多個 Student 呢?

利用flatmap程式碼如下:

Observable
                .from(persons)
                .flatMap(new Func1<Person, Observable<Address>>() {
                    @Override
                    public Observable<Address> call(Person person) {
                        return Observable.from(person.getAddresses());
                    }
                })
                .subscribe(new Subscriber<Address>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(Address address) {
                        Log.e(TAG, "onNext: address = " + address.getAddressName());
                    }
});

從上面的程式碼可以看出, flatMap() 和 map() 有一個相同點:它也是把傳入的引數轉化之後返回另一個物件。但需要注意,和 map() 不同的是, flatMap() 中返回的是個 Observable 物件,並且這個 Observable 物件並不是被直接傳送到了 Subscriber 的回撥方法中。 flatMap() 的原理是這樣的:1. 使用傳入的事件物件建立一個 Observable 物件;2. 並不傳送這個 Observable, 而是將它啟用,於是它開始傳送事件;3. 每一個創建出來的 Observable 傳送的事件,都被匯入同一個 Observable ,而這個 Observable 負責將這些事件統一交給 Subscriber 的回撥方法。這三個步驟,把事件拆成了兩級,通過一組新建立的 Observable 將初始的物件『鋪平』之後通過統一路徑分發了下去。而這個『鋪平』就是 flatMap() 所謂的 flat。