值得收藏的圖解Rxjava Operators

本文中經過圖解的方式解釋Rxjava中複雜的操做符,值得收藏。其中用到的demo地址:RxJava2-Android-Samplesjavascript

1. buffer


demo:
Observable<List<String>> buffered = getObservable().buffer(2, 3);
第一個參數表示在emit數據以前,Observable須要緩存多少個數據
第二個參數表示每次emit數據以後跳過幾個數據。

圖示中就是每次buffer 2個數據以後emit,每次emit以後跳過3個數據。html

2. concat


demo:
Observable.concat(aObservable, bObservable)
第一個參數爲第一個Observable
第二個參數爲第二個Observable
圖示中鏈接兩個Observable以後,數據會鏈接起來,emit a1, a2, a3,b1,b2,b3

3. debounce

demo:
getObservable() .debounce(500, TimeUnit.MILLISECONDS)
第一個參數是時間間隔
第二個參數是時間單位
debounce表示emit數據以後必定時間內沒有其餘數據出現才真正emit數據。
圖示中emit黃球后,在規定時間內又emit綠球,則黃球不會被emit。java

4. defer

defer爲每個observer建立一個ObservableSource,這樣當第一個observer訂閱以後若是ObservableSource中的數據發生變化,第二個訂閱的Observer會獲得不一樣的數據。react

demo:git

Observable.defer(new Callable<ObservableSource<? extends String>>() {
            @Override
            public ObservableSource<? extends String> call() throws Exception {
                return Observable.just(brand);
            }
        });複製代碼

demo中能夠隨時改變brand的值,這樣不一樣的Observer可能會獲得不一樣的值。github

5. distinct

distinct能夠對 emit 的數據作去重處理
demo:api

Observable.just(1, 2, 1, 1, 2, 3, 4 ,6, 4)
                    .distinct() 
                    .subscribe(getObserver());複製代碼

demo中最後emit的數據只有1,2,3,4,6緩存

6. filter

filter按照必定的規則過濾數據
demo:app

Observable.just(1, 2, 3, 4, 5, 6)
                .filter(new Predicate<Integer>() {
                    @Override
                    public boolean test(Integer integer) throws Exception {
                        return integer % 2 == 0;
                    }
                })
                .subscribe(getObserver());複製代碼

demo中原始數據中奇數會被過濾掉。ide

7. reduce


reduce 對全部數據進行處理,最終emit一個數據。
demo:

Flowable<Integer> observable = Flowable.just(1, 2, 3, 4);

        observable.reduce(50, new BiFunction<Integer, Integer, Integer>() {
            @Override
            public Integer apply(Integer t1, Integer t2) {
                return t1 + t2;
            }
        }).subscribe(getObserver());複製代碼

demo中把 50 + 1 +2 +3 +4 的結果60 emit。

8. interval


demo:
Observable.interval(0, 2, TimeUnit.SECONDS);
interval能夠延時必定時間後開始按週期emit數據,emit的數據從0開始一次遞增。
第一個參數爲第一次emit數據時延時時間
第二個參數爲emit數據週期
第三個參數爲時間單位

9 .last

若是Observable有數據則只emit最後一個數據,若是沒有數據則emit默認數據。

demo:

Observable.just("A1", "A2", "A3", "A4", "A5", "A6").last("A1") // the default item ("A1") to emit if the source ObservableSource is empty
                .subscribe(getObserver());複製代碼

demo中只emit A6,若是Observable沒有數據,則會emit 默認數據A1。

10. map


map能夠對數據執行一些操做後再emit出去。
demo:

getObservable()
                // Run on a background thread
                .subscribeOn(Schedulers.io())
                // Be notified on the main thread
                .observeOn(AndroidSchedulers.mainThread())
                .map(new Function<List<ApiUser>, List<User>>() {

                    @Override
                    public List<User> apply(List<ApiUser> apiUsers) throws Exception {
                        return Utils.convertApiUserListToUserList(apiUsers);
                    }
                })
                .subscribe(getObserver());複製代碼

demo中把一個ApiUser list轉爲 User list 了。

11. merge

merge 與concat不一樣的是把兩個 Observable的數據合成一列數據,就像是從一個Observable emit,可是順序不必定。
demo:

final String[] aStrings = {"A1", "A2", "A3", "A4"};
        final String[] bStrings = {"B1", "B2", "B3"};

        final Observable<String> aObservable = Observable.fromArray(aStrings);
        final Observable<String> bObservable = Observable.fromArray(bStrings);

        Observable.merge(aObservable, bObservable)
                .subscribe(getObserver());複製代碼

demo 中最終emit的數據多是"A1", "B1", "A2", "A3", "A4", "B2", "B3",還多是其餘順序。

12. scan

demo:

Observable.just(1, 2, 3, 4, 5)
                // Run on a background thread
                .subscribeOn(Schedulers.io())
                // Be notified on the main thread
                .observeOn(AndroidSchedulers.mainThread())
                .scan(new BiFunction<Integer, Integer, Integer>() {
                    @Override
                    public Integer apply(Integer int1, Integer int2) throws Exception {
                        return int1 + int2;
                    }
                })
                .subscribe(getObserver());複製代碼

demo中依次輸出1,3,6,10,15,即依次把BiFunction做用在前一個輸出結果和當前數據上。

13. skip

demo:

Observable.just(1, 2, 3, 4, 5)
                // Run on a background thread
                .subscribeOn(Schedulers.io())
                // Be notified on the main thread
                .observeOn(AndroidSchedulers.mainThread())
                .skip(3)
                .subscribe(getObserver());複製代碼

skip比較簡單,會跳過前幾個數據,具體能夠經過參數設置,demo中是跳過前三個數據。

14. take


demo:

Observable.just(1, 2, 3, 4, 5)
                // Run on a background thread
                .subscribeOn(Schedulers.io())
                // Be notified on the main thread
                .observeOn(AndroidSchedulers.mainThread())
                .take(3)
                .subscribe(getObserver());複製代碼

take比較簡單,只取前幾個數據emit,demo中取前三個數據。

15. throttleLast


throttleLast emit必定週期內的最後一個數據。

demo:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                // send events with simulated time wait
                Thread.sleep(0);
                emitter.onNext(1); // skip
                emitter.onNext(2); // deliver
                Thread.sleep(505);
                emitter.onNext(3); // skip
                Thread.sleep(99);
                emitter.onNext(4); // skip
                Thread.sleep(100);
                emitter.onNext(5); // skip
                emitter.onNext(6); // deliver
                Thread.sleep(305);
                emitter.onNext(7); // deliver
                Thread.sleep(510);
                emitter.onComplete();
            }
        }).throttleLast(500, TimeUnit.MILLISECONDS)
                // Run on a background thread
                .subscribeOn(Schedulers.io())
                // Be notified on the main thread
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(getObserver());複製代碼

demo中每隔500ms emit當時的最後一個數據,demo中最終emit 2,6,7。

16. timer

timer比較簡單,就是延時必定時間emit 數據0。
demo:

Observable.timer(2, TimeUnit.SECONDS)
                // Run on a background thread
                .subscribeOn(Schedulers.io())
                // Be notified on the main thread
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(getObserver());複製代碼

17 zip


demo:

private void doSomeWork() {
        Observable.zip(getCricketFansObservable(), getFootballFansObservable(),
                new BiFunction<List<User>, List<User>, List<User>>() {
                    @Override
                    public List<User> apply(List<User> cricketFans, List<User> footballFans) throws Exception {
                        return Utils.filterUserWhoLovesBoth(cricketFans, footballFans);
                    }
                })
                // Run on a background thread
                .subscribeOn(Schedulers.io())
                // Be notified on the main thread
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(getObserver());
    }

    private Observable<List<User>> getCricketFansObservable() {
        return Observable.create(new ObservableOnSubscribe<List<User>>() {
            @Override
            public void subscribe(ObservableEmitter<List<User>> e) throws Exception {
                if (!e.isDisposed()) {
                    e.onNext(Utils.getUserListWhoLovesCricket());
                    e.onComplete();
                }
            }
        });
    }

    private Observable<List<User>> getFootballFansObservable() {
        return Observable.create(new ObservableOnSubscribe<List<User>>() {
            @Override
            public void subscribe(ObservableEmitter<List<User>> e) throws Exception {
                if (!e.isDisposed()) {
                    e.onNext(Utils.getUserListWhoLovesFootball());
                    e.onComplete();
                }
            }
        });
    }

    public static List<User> filterUserWhoLovesBoth(List<User> cricketFans, List<User> footballFans) {
        List<User> userWhoLovesBoth = new ArrayList<User>();
        for (User cricketFan : cricketFans) {
            for (User footballFan : footballFans) {
                if (cricketFan.id == footballFan.id) {
                    userWhoLovesBoth.add(cricketFan);
                }
            }
        }
        return userWhoLovesBoth;
    }複製代碼

zip對兩個Observable的數據進行BiFunction操做,以後再emit出去。demo中getCricketFansObservable 獲取到喜歡cricket 的人,getFootballFansObservable獲取到喜歡football的人,最終通過BiFunction以後獲取到喜歡兩項運動的人。

關於Rxjava的更多operators能夠參考其官網,地址:reactivex.io/documentati…

相關文章
相關標籤/搜索