RxJava操作符系列六 | 掘金技術徵文

Code4Android發表於2016-12-19

RxJava操作符系列傳送門

RxJava操作符原始碼
RxJava操作符系列一
RxJava操作符系列二
RxJava操作符系列三
RxJava操作符系列四
RxJava操作符系列五

前言

在上幾篇文章我們介紹了一些RxJava建立,轉換,過濾,組合,輔助的一些操作符,今天我們繼續去學習RxJava的一些條件和布林操作符,在此感謝那些閱讀文章並提出建議的同學,其實寫技術文章主要是提升自己的知識面以及對知識的理解程度,也有人說有些地方描述還不夠清晰,文筆有待提高,是的,確實是這樣,描述不清晰我感覺不僅是文筆有待提高(提升空間很大),對技術的理解也需要提高(技術渣蛻變中...)。不過我相信,只要我能寫出來,這就是一種進步,就是一個積累的過程,我會努力,加油。好了,不扯了,進入正題。

All

該操作符是判斷Observable發射的所有資料是否都滿足某一條件,它接收一個Fun1方法引數,此方法接收原始資料,並返回一個布林型別值,如果原始Observable正常終止並且每一項資料都滿足條件,就返回true;如果原始Observable的任何一項資料不滿足條件就返回False。當某資料不滿足條件(返回false)時之後的資料不再發射。如下示例程式碼

 Observable.just(1,2,3,4).all(new Func1<Integer, Boolean>() {
            @Override
            public Boolean call(Integer integer) {
                Log.e(TAG, "call: "+integer );
                return integer<2;
            }
        }).subscribe(new Subscriber<Boolean>() {
            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted: ");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError: " );
            }

            @Override
            public void onNext(Boolean aBoolean) {
                Log.e(TAG, "onNext: "+aBoolean );
            }
        });複製程式碼

輸出日誌資訊

call: 1
call: 2
onNext: false
onCompleted:複製程式碼

Amb

當我們傳遞多個Observable(可接收2到9個Observable)給amb時,它只發射其中一個Observable的資料和通知:首先傳送通知給amb的那個,不管發射的是一項資料還是一個onError或onCompleted通知。amb將忽略和丟棄其它所有Observables的發射物。

RxJava操作符系列六 | 掘金技術徵文
這裡寫圖片描述

 Observable observable= Observable.just(1,2,3).delay(500,TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread());
       Observable observable1= Observable.just(4,5,6).delay(100,TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread());
        Observable.amb(observable,observable1).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted: ");
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError: ");
            }

            @Override
            public void onNext(Integer integer) {
                Log.e(TAG, "  onNext: "+integer);
            }
        });複製程式碼

輸出日誌資訊

onNext: 4
onNext: 5
onNext: 6
onCompleted:複製程式碼

有一個類似的物件方法ambWith。如上示例中Observable.amb(observable,observable1)改為observable.ambWith(observable1)是等價的。

Contains

我們可以給Contains傳一個指定的值,如果原始Observable發射了那個值,它返回的Observable將發射true,否則發射false,即Observable發射的資料是否包含某一物件。
示例程式碼

Observable.just(1,2,3,4).contains(2)
                .subscribe(new Subscriber<Boolean>() {
                    @Override
                    public void onCompleted() {
                        Log.e(TAG, "onCompleted: " );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "onError: " );
                    }

                    @Override
                    public void onNext(Boolean aBoolean) {
                        Log.e(TAG, "onNext: "+aBoolean);
                    }
                });複製程式碼

輸出日誌資訊

onNext: true
onCompleted:複製程式碼

isEmpty也是一種判斷是否包含的操作符,不同的是它判斷原始Observable是否沒有發射任何資料。

exists操作符與contains操作符作用相同,但是它接收的是一個Func1函式,可以指定一個判斷條件,當發射的資料有滿足判斷條件(返回true)就發射true,否則為false。

DefaultIfEmpty

該操作符簡單的精確地發射原始Observable的值,如果原始Observable沒有發射任何資料正常終止(以onCompletedd的形式),DefaultIfEmpty返回的Observable就發射一個我們提供的預設值。

Observable.empty().defaultIfEmpty(1).subscribe(new Subscriber<Object>() {

            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted: " );
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError: ");
            }

            @Override
            public void onNext(Object object) {
                Log.e(TAG, "onNext: "+object);
            }
        });複製程式碼

輸出日誌資訊

onNext: 1
onCompleted:複製程式碼

defaultIfEmpty只有在沒有發射資料時才會有效果,若發射的有資料,和不使用此操作符效果一樣。

SequenceEqual

該操作符會比較兩個Observable的發射物,如果兩個序列是相同的(相同的資料,相同的順序,相同的終止狀態),它就發射true,否則發射false

  Observable observable=Observable.just(1,2,3);
        Observable observable1=Observable.just(1,3,2);
        Observable.sequenceEqual(observable,observable1)
                .subscribe(new Subscriber<Boolean>() {
                    @Override
                    public void onCompleted() {
                        Log.e(TAG, "onCompleted: " );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "onError: " );
                    }

                    @Override
                    public void onNext(Boolean aBoolean) {
                        Log.e(TAG, "onNext: " +aBoolean);
                    }
                });複製程式碼

執行後輸出

onNext: false
onCompleted:複製程式碼

SkipUntil

SkipUntil訂閱原始的Observable,但是忽略它的發射物,直到第二個Observable發射了一項資料那一刻,它開始發射原始Observable。

RxJava操作符系列六 | 掘金技術徵文
這裡寫圖片描述

Observable observable = Observable.just(1, 2, 3,4,5,6).delay(100, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread());
        Observable observable1 = Observable.just(20, 21, 22).delay(130, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread());
        observable.skipUntil(observable1)
               .subscribe(new Subscriber() {
                   @Override
                   public void onCompleted() {
                       Log.e(TAG, "onCompleted: " );
                   }

                   @Override
                   public void onError(Throwable e) {
                       Log.e(TAG, "onError: " );
                   }

                   @Override
                   public void onNext(Object o) {
                       Log.e(TAG, "onNext: "+o );
                   }
               });複製程式碼

輸出日誌資訊

onNext: 4
onNext: 5
onNext: 6
onCompleted:複製程式碼

由於上面兩個Observable都是在一個新執行緒中,時間不可控,每次執行的結果一般不會相同。但是都會符合上面所述規則,可參考上圖。

SkipWhile

該操作符也是忽略它的發射物,直到我們指定的某個條件變為false的那一刻,它開始發射原始Observable。切記是判斷條件返回false時開始發射資料。
示例程式碼

 Observable.range(1,5).skipWhile(new Func1<Integer, Boolean>() {
            @Override
            public Boolean call(Integer integer) {
                Log.e(TAG, "call: "+integer);
                return integer<3;
            }
        }).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted: " );
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError: " );
            }

            @Override
            public void onNext(Integer integer) {
                Log.e(TAG, "onNext: " +integer);
            }
        });複製程式碼

輸出日誌資訊

call: 1
call: 2
call: 3
onNext: 3
onNext: 4
onNext: 5
onCompleted:複製程式碼

TakeUntil

如果我們理解了SkipUntil操作符了,那麼這個操作符也就很好理解了,該操作符與SkipUntil有點相反的意思。

RxJava操作符系列六 | 掘金技術徵文
這裡寫圖片描述

通過上圖你應該也看出來和SkipUntil的區別,當第二個Observable發射了一項資料或者終止時,丟棄原始Observable發射的任何資料(SkipUntil則是丟棄之前資料,發射之後的資料)。

Observable observable = Observable.just(1, 2, 3,4,5,6).delay(100, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread());
        Observable observable1 = Observable.just(20, 21, 22).delay(120, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread());
        observable.takeUntil(observable1)
                .subscribe(new Subscriber() {
                    @Override
                    public void onCompleted() {
                        Log.e(TAG, "onCompleted: " );
                    }

                    @Override
                    public void onError(Throwable e) {
                        Log.e(TAG, "onError: " );
                    }

                    @Override
                    public void onNext(Object o) {
                        Log.e(TAG, "onNext: "+o );
                    }
                });複製程式碼

輸出日誌資訊(每次執行的輸出結果一般不相同)

onNext: 1
onNext: 2
onNext: 3
onNext: 4
onCompleted:複製程式碼

TakeWhile

該操作符發射原始Observable,直到我們指定的某個條件不成立的那一刻,它停止發射原始Observable(skipWhile此時開始發射),並終止自己的Observable。

 Observable.range(1,5).takeWhile(new Func1<Integer, Boolean>() {
            @Override
            public Boolean call(Integer integer) {
                Log.e(TAG, "call: "+integer);
                return integer<3;
            }
        }).subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                Log.e(TAG, "onCompleted: " );
            }

            @Override
            public void onError(Throwable e) {
                Log.e(TAG, "onError: " );
            }

            @Override
            public void onNext(Integer integer) {
                Log.e(TAG, "onNext: " +integer);
            }
        });複製程式碼

輸出日誌資訊

call: 1
onNext: 1
call: 2
onNext: 2
call: 3
onCompleted:複製程式碼

今天的這篇文章到這裡就結束了,若文中有錯誤的地方,歡迎指正。謝謝。

掘金活動連結 gold.xitu.io/post/58522d…

相關文章