Android從零開始學習Rxjava2(四)—— Map

rxjava2變換運算符

Map

將Observable發出的每個項目通過函數應用轉換後發出。
在這裏插入圖片描述
上面的圖很好的解釋了map方法的含義。在工作中也很常遇見這種情況,源Observable發出的項,不是我們直接想要的,這時候就需要對Observable發出的項變換處理。舉個例子:

private void doSomeWork() {
        Observable.just("0", "1", "2", "3", "4", "5", "6", "7", "8", "9")
                .map(new Function<String, String>() {
                    @Override
                    public String apply(String s) throws Exception {
                        return "this is map apply s is " + s;
                    }
                })
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String value) throws Exception {
                        Log.d(TAG, " accept : value : " + value);
                    }
                });
    }

打印結果

accept : value : this is map apply s is 0
accept : value : this is map apply s is 1
accept : value : this is map apply s is 2
accept : value : this is map apply s is 3
accept : value : this is map apply s is 4
accept : value : this is map apply s is 5
accept : value : this is map apply s is 6
accept : value : this is map apply s is 7
accept : value : this is map apply s is 8
accept : value : this is map apply s is 9

源發出去的是string類型的字符串0,1,2等等,通過map中函數裏面的方法,我們變換處理了源Observable發出的項,轉換後發出的類型可以是任何類型,我們這裏處理後還是string,只是將數據內容改變了下。

FlatMap

將Observable發出的項目轉換爲Observables,然後將這些項目的排放量變爲單個Observable。FlatMap運算符通過將您指定的函數應用於源Observable發出的每個項來轉換Observable,其中該函數返回一個本身發出項的Observable。FlatMap合併這些結果Observable的發射,將這些合併的結果作爲自己的序列發出。

請注意,FlatMap會合並這些Observable的發射,但它們可能交錯。

在這裏插入圖片描述
上面我們已經瞭解了rxjava中Map的方法,FlatMap比Map多了一層意思,就是flat平鋪。Map只是對源Observable發出的項簡單的一對一用函數轉換,FlatMap可以對源Observable發出的項用函數分解或者擴展成多個項,然後將所有的項平鋪的發送出來。
舉個例子,源Observable只發送int數據0,1,2,3,經過FlatMap裏的函數擴展後,發射出來的數據變成了3倍。

private void doSomeWork() {
        Observable.just(0, 1, 2, 3)
                .flatMap(new Function<Integer, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(Integer integer) throws Exception {
                        List<String> list = new ArrayList<>();
                        for (int i = 0; i < 3; i++) {
                            list.add("apply data is " + integer + ",i is " + i);
                        }
                        return Observable.fromIterable(list).delay((3 - integer) * 10, TimeUnit.MILLISECONDS);
                    }
                })
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String value) throws Exception {
                        Log.d(TAG, " accept : value : " + value);
                    }
                });
    }

打印結果

accept : value : apply data is 3,i is 0
accept : value : apply data is 3,i is 1
accept : value : apply data is 3,i is 2
accept : value : apply data is 2,i is 0
accept : value : apply data is 2,i is 1
accept : value : apply data is 2,i is 2
accept : value : apply data is 1,i is 0
accept : value : apply data is 1,i is 1
accept : value : apply data is 1,i is 2
accept : value : apply data is 0,i is 0
accept : value : apply data is 0,i is 1
accept : value : apply data is 0,i is 2

由於FlatMap合併數據的時候採用的是merge但方法,所以可以看見最終發射出來的項順序和源發射出來的項順序不一定對應。這就是上面說的它們可能交錯。如果想最終變換後的項順序和源發出的順序一致,可以看看下面的concatMap。

concatMap

作用和FlatMap一樣,只是與FlatMap不同的是,他最終輸出的項順序和源發出的項順序是一致的。
在這裏插入圖片描述
將上面FlatMap的例子改成concatMap,我們可以看看打印的結果來比較下區別

private void doSomeWork() {
        Observable.just(0, 1, 2, 3)
                .concatMap(new Function<Integer, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(Integer integer) throws Exception {
                        List<String> list = new ArrayList<>();
                        for (int i = 0; i < 3; i++) {
                            list.add("apply data is " + integer + ",i is " + i);
                        }
                        return Observable.fromIterable(list).delay((3 - integer) * 10, TimeUnit.MILLISECONDS);
                    }
                })
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String value) throws Exception {
                        Log.d(TAG, " accept : value : " + value);
                    }
                });
    }

打印結果

accept : value : apply data is 0,i is 0
accept : value : apply data is 0,i is 1
accept : value : apply data is 0,i is 2
accept : value : apply data is 1,i is 0
accept : value : apply data is 1,i is 1
accept : value : apply data is 1,i is 2
accept : value : apply data is 2,i is 0
accept : value : apply data is 2,i is 1
accept : value : apply data is 2,i is 2
accept : value : apply data is 3,i is 0
accept : value : apply data is 3,i is 1
accept : value : apply data is 3,i is 2

可以看見concatMap結果集的順序和按照源發出的順序一致

flatMapIterable

flatMapIterable和FlatMap的工作方式大致相同,不同的是對源項處理生成Iterables而不是生成Observable。
在這裏插入圖片描述
其實flatMapIterable就是一個可以自動迭代循環處理結果集的flatMap。
一樣舉個例子

private void doSomeWork() {
        Observable.just(0, 1, 2, 3)
                .flatMapIterable(new Function<Integer, Iterable<String>>() {
                    @Override
                    public Iterable<String> apply(Integer integer) throws Exception {
                        List<String> list = new ArrayList<>();
                        for (int i = 0; i < 3; i++) {
                            list.add("apply data is " + integer + ",i is " + i);
                        }
                        return list;
                    }
                })
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String value) throws Exception {
                        Log.d(TAG, " accept : value : " + value);
                    }
                });
    }

打印結果

accept : value : apply data is 0,i is 0
accept : value : apply data is 0,i is 1
accept : value : apply data is 0,i is 2
accept : value : apply data is 1,i is 0
accept : value : apply data is 1,i is 1
accept : value : apply data is 1,i is 2
accept : value : apply data is 2,i is 0
accept : value : apply data is 2,i is 1
accept : value : apply data is 2,i is 2
accept : value : apply data is 3,i is 0
accept : value : apply data is 3,i is 1
accept : value : apply data is 3,i is 2

對於map相關的就簡單的寫這些,其他的map方法也都是思路大同小異,最多也只是對結果特殊的處理了下,類似flatMapIterable和flatMap之間的差異,我就不一一舉例說明了。


參考資料,參考但不侷限以下鏈接
http://reactivex.io/documentation/operators/flatmap.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章