RxJava操作符(07-輔助操作)

版權聲明:本文爲openXu原創文章【openXu的博客】,未經博主允許不得以任何形式轉載

目錄:

1. Delay

  delay的意思就是延遲,這個操作符會延遲一段指定的時間再發射Observable的數據。 RxJava的實現是 delay和delaySubscription。

  • delay:讓原始Observable在發射每項數據之前都暫停一段指定的時間段,結果是Observable發射的數據項在時間上整體延後一段時間
    注意:delay不會平移onError通知,它會立即將這個通知傳遞給訂閱者,同時丟棄任何待發射的onNext通知。但是它會平移一個onCompleted通知。

    這裏寫圖片描述

  • delaySubscription:和delay不同的是,delaySubscription是延遲訂閱原始Observable,這樣也能達到數據延遲發射的效果

    這裏寫圖片描述

示例代碼:

Observable<Integer> obs = Observable.create(new Observable.OnSubscribe<Integer>() {
    @Override
    public void call(Subscriber<? super Integer> subscriber) {
        for(int i =0;i<5;i++){
            if(i>2){
                subscriber.onError(new Throwable("VALUE TO MAX"));
            }
            subscriber.onNext(i);
        }
        subscriber.onCompleted();
    }
}).subscribeOn(Schedulers.computation());

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
/*
 * Delay操作符讓原始Observable在發射每項數據之前都暫停一段指定的時間段。
 * 效果是Observable發射的數據項在時間上向前整體平移了一個增量
 *
 * 注意:delay不會平移onError通知,它會立即將這個通知傳遞給訂閱者,同時丟棄任何待發射的onNext通知。
 * 然而它會平移一個onCompleted通知。
 */
Log.v(TAG, "delay start:" + sdf.format(new Date()));
obs.delay(2, TimeUnit.SECONDS)
        .subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                Log.v(TAG, "delay onCompleted" + sdf.format(new Date()));
            }
            @Override
            public void onError(Throwable e) {
                Log.v(TAG, "delay onError"+e.getMessage());
            }
            @Override
            public void onNext(Integer integer) {
                Log.v(TAG, "delay onNext:" + sdf.format(new Date())+"->"+integer);
            }
        });

/*
 * delaySubscription:延遲訂閱原始Observable
 */
Log.v(TAG, "delaySubscription start:" + sdf.format(new Date()));
obs.delaySubscription(2, TimeUnit.SECONDS)
        .subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                Log.v(TAG, "delaySubscription onCompleted" + sdf.format(new Date()));
            }

            @Override
            public void onError(Throwable e) {
                Log.v(TAG, "delaySubscription onError"+e.getMessage());
            }

            @Override
            public void onNext(Integer integer) {
                Log.v(TAG, "delaySubscription onNext:" + sdf.format(new Date())+"->"+integer);
            }
        });

輸出:

delay start:01:02:15
delay onErrorVALUE TO MAX

delaySubscription start:01:02:15
delaySubscription onNext:01:02:17->0
delaySubscription onNext:01:02:17->1
delaySubscription onNext:01:02:17->2
delaySubscription onErrorVALUE TO MAX

分析:
  原始Observable會發射3個整數,然後發送onError通知。delay操作符會讓每個發射的數據延遲2s發射出去,但由於原始Observable在2s之內發射了onError消息,而delay不會延遲onError通知,會立即傳遞給觀察者,所以馬上就結束了。

  而delaySubscription是延遲訂閱,這個更好理解,就是原始Observable該怎麼發射消息還是怎麼發射,因爲只有訂閱之後纔會開始發射消息,所以延遲2s。

2. Do

  Do系列操作符就是爲原始Observable的生命週期事件註冊一個回調,當Observable的某個事件發生時就會調用這些回調。RxJava實現了很多doxxx操作符:

    這裏寫圖片描述

  • doOnEach:爲 Observable註冊這樣一個回調,當Observable沒發射一項數據就會調用它一次,包括onNext、onError和 onCompleted
  • doOnNext:只有執行onNext的時候會被調用
  • doOnSubscribe: 當觀察者(Sunscriber)訂閱Observable時就會被調用
  • doOnUnsubscribe: 當觀察者取消訂閱Observable時就會被調用;Observable通過onError或者onCompleted結束時,會反訂閱所有的Subscriber
  • doOnCompleted:當Observable 正常終止調用onCompleted時會被調用。
  • doOnError: 當Observable 異常終止調用onError時會被調用。
  • doOnTerminate: 當Observable 終止之前會被調用,無論是正常還是異常終止
  • finallyDo: 當Observable 終止之後會被調用,無論是正常還是異常終止。

示例代碼:

Log.v(TAG,"doOnNext------------------------");
Observable.just(1, 2, 3)
        //只有onNext的時候纔會被觸發
        .doOnNext(new Action1<Integer>() {
            @Override
            public void call(Integer item) {
                Log.v(TAG,"-->doOneNext: " + item);
            }
        }).subscribe(new Subscriber<Integer>() {
    @Override
    public void onNext(Integer item) {
        Log.v(TAG,"Next: " + item);
    }
    @Override
    public void onError(Throwable error) {
        Log.v(TAG,"Error: " + error.getMessage());
    }
    @Override
    public void onCompleted() {
        Log.v(TAG,"Sequence complete.");
    }
});

Log.v(TAG,"doOnEach,doOnError------------------------");
Observable.just(1, 2, 3)
        //Observable每發射一個數據的時候就會觸發這個回調,不僅包括onNext還包括onError和onCompleted
        .doOnEach(new Action1<Notification<? super Integer>>() {
            @Override
            public void call(Notification<? super Integer> notification) {
                Log.v(TAG,"-->doOnEach: " +notification.getKind()+":"+ notification.getValue());
                if( (int)notification.getValue() > 1 ) {
                    throw new RuntimeException( "Item exceeds maximum value" );
                }
            }
        })
        //Observable異常終止調用onError時會被調用
        .doOnError(new Action1<Throwable>() {
            @Override
            public void call(Throwable throwable) {
                Log.v(TAG,"-->doOnError: "+throwable.getMessage() );
            }
        })
        .subscribe(new Subscriber<Integer>() {
    @Override
    public void onNext(Integer item) {
        Log.v(TAG,"Next: " + item);
    }
    @Override
    public void onError(Throwable error) {
        Log.v(TAG,"Error: " + error.getMessage());
    }
    @Override
    public void onCompleted() {
        Log.v(TAG,"Sequence complete.");
    }
});


Log.v(TAG,"doxxx------------------------");
Observable.just(1, 2, 3)
        .doOnCompleted(new Action0() {
            @Override
            public void call() {
                Log.v(TAG,"-->doOnCompleted:正常完成onCompleted");  //數據序列發送完畢回調
            }
        })
        .doOnSubscribe(() -> Log.v(TAG,"-->doOnSubscribe:被訂閱"))   //被訂閱時回調
        //反訂閱(取消訂閱)時回調。當一個Observable通過OnError或者OnCompleted結束的時候,會反訂閱所有的Subscriber
        .doOnUnsubscribe(() -> Log.v(TAG,"-->doOnUnsubscribe:反訂閱"))
        //Observable終止之前會被調用,無論是正常還是異常終止
        .doOnTerminate(() -> Log.v(TAG,"-->doOnTerminate:終止之前"))
        //Observable終止之後會被調用,無論是正常還是異常終止
        .finallyDo(() -> Log.v(TAG,"-->finallyDo:終止之後"))
        .subscribe(new Subscriber<Integer>() {
    @Override
    public void onNext(Integer item) {
        Log.v(TAG,"Next: " + item);
    }
    @Override
    public void onError(Throwable error) {
        Log.v(TAG,"Error: " + error.getMessage());
    }
    @Override
    public void onCompleted() {
        Log.v(TAG,"Sequence complete.");
    }
});

輸出:

doOnNext------------------------
–>doOneNext: 1
Next: 1
–>doOneNext: 2
Next: 2
–>doOneNext: 3
Next: 3
Sequence complete.

doOnEach,doOnError------------------------
–>doOnEach: OnNext:1
Next: 1
–>doOnEach: OnNext:2
–>doOnEach: OnError:null
–>doOnError: 2 exceptions occurred.
Error: 2 exceptions occurred.

doxxx------------------------
–>doOnSubscribe:被訂閱
Next: 1
Next: 2
Next: 3
–>doOnCompleted:正常完成onCompleted
–>doOnTerminate:終止之前
Sequence complete.
–>doOnUnsubscribe:反訂閱
–>finallyDo:終止之後

3. Materialize/Dematerialize

  • materialize將來自原始Observable的通知(onNext/onError/onComplete)都轉換爲一個Notification對象,然後再按原來的順序一次發射出去。
  • Dematerialize操作符是Materialize的逆向過程,它將Materialize轉換的結果還原成它原本的形式( 將Notification對象還原成Observable的通知)

    這裏寫圖片描述

示例代碼:

Observable<Integer> obs = Observable.create(new Observable.OnSubscribe<Integer>() {
    @Override
    public void call(Subscriber<? super Integer> subscriber) {
        for(int i = 0;i<3; i++){
            subscriber.onNext(i);
        }
        subscriber.onCompleted();
    }
});

Log.v(TAG, "materialize-----------");
obs.materialize()
        .subscribe(new Subscriber<Notification<Integer>>() {
           @Override
            public void onCompleted() {
               Log.v(TAG,"Sequence complete.");
            }

            @Override
            public void onError(Throwable e) {
                Log.v(TAG,"onError:"+e.getMessage());
            }
            //將所有的消息封裝成Notification後再發射出去
            @Override
            public void onNext(Notification<Integer> integerNotification) {
                Log.v(TAG,"onNext:"+integerNotification.getKind()+":"+integerNotification.getValue());
            }
        });

Log.v(TAG, "dematerialize-----------");
obs.materialize()
    //將Notification逆轉爲普通消息發射
   .dematerialize()
   .subscribe(integer->Log.v(TAG, "deMeterialize:"+integer));

輸出:

materialize-----------
onNext:OnNext:0
onNext:OnNext:1
onNext:OnNext:2
onNext:OnCompleted:null
Sequence complete.

dematerialize-----------
deMeterialize:0
deMeterialize:1
deMeterialize:2

4. ObserveOn/SubscribeOn

  這兩個操作符對於Android開發來說非常適用,因爲Android中只能在主線程中修改UI,耗時操作不能在主線程中執行,所以我們經常會創建新的Thread去執行耗時操作,然後配合Handler修改UI,或者使用AsyncTask。RxJava中使用這兩個操作符能夠讓我們非常方便的處理各種線程問題。

  • SubscribeOn:指定Observable自身在哪個調度器上執行(即在那個線程上運行),如果Observable需要執行耗時操作,一般我們可以讓其在新開的一個子線程上運行,好比AsyncTask的doInBackground方法。
        這裏寫圖片描述

  • Observable。可以使用observeOn操作符指定Observable在哪個調度器上發送通知給觀察者(調用觀察者的onNext,onCompleted,onError方法)。一般我們可以指定在主線程中觀察,這樣就可以修改UI,相當於AsyncTask的onPreExecute 、onPrograssUpdate和onPostExecute 方法中執行

    這裏寫圖片描述

關於RxJava的多線程調度器“Scheduler”,後面會有一篇博客詳細介紹。

示例代碼:

Observable<Integer> obs = Observable.create(new Observable.OnSubscribe<Integer>() {
    @Override
    public void call(Subscriber<? super Integer> subscriber) {
        Log.v(TAG, "on subscrib:" + Thread.currentThread().getName());
        subscriber.onNext(1);
        subscriber.onCompleted();
    }
});

//在新建子線程中執行,在主線程中觀察
obs.subscribeOn(Schedulers.newThread())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(i ->  Log.v(TAG, "mainThread-onNext:" + Thread.currentThread().getName()));

obs.delaySubscription(2, TimeUnit.SECONDS)
        .subscribeOn(Schedulers.computation())  //用於計算任務,如事件循環或和回調處理
        .observeOn(Schedulers.immediate())      //在當前線程立即開始執行任務
        .subscribe(i ->  Log.v(TAG, "immediate-onNext:" + Thread.currentThread().getName()));

輸出:

on subscrib:RxNewThreadScheduler-4
mainThread-onNext:main

on subscrib:RxComputationScheduler-1
immediate-onNext:RxComputationScheduler-1

5. TimeInterval

  TimeInterval操作符攔截原始Observable發射的數據項,替換爲兩個連續發射物之間流逝的時間長度。 也就是說這個使用這個操作符後發射的不再是原始數據,而是原始數據發射的時間間隔。新的Observable的第一個發射物表示的是在觀察者訂閱原始Observable到原始Observable發射它的第一項數據之間流逝的時間長度。 不存在與原始Observable發射最後一項數據和發射onCompleted通知之間時長對應的發射物。timeInterval默認在immediate調度器上執行,你可以通過傳參數修改。

    這裏寫圖片描述

示例代碼:

Observable.create(new Observable.OnSubscribe<Integer>() {
    @Override
    public void call(Subscriber<? super Integer> subscriber) {
        for (int i = 0; i <= 3; i++) {
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            subscriber.onNext(i);
        }
        subscriber.onCompleted();
    }
}).subscribeOn(Schedulers.newThread())
        .timeInterval()
        .subscribe(new Subscriber<TimeInterval<Integer>>() {
            @Override
            public void onCompleted() {
                Log.v(TAG, "onCompleted");
            }
            @Override
            public void onError(Throwable e) {
                Log.v(TAG, "onError:"+e.getMessage());
            }
            @Override
            public void onNext(TimeInterval<Integer> integerTimeInterval) {
                Log.v(TAG, "onNext:"+integerTimeInterval.getValue()+
                        "-"+integerTimeInterval.getIntervalInMilliseconds());
            }
        });

輸出:

onNext:0-1010
onNext:1-1002
onNext:2-1000
onNext:3-1001
onCompleted

6. Timeout

  如果原始Observable過了指定的一段時長沒有發射任何數據,Timeout操作符會以一個onError通知終止這個Observable,或者繼續一個備用的Observable。

    這裏寫圖片描述

RxJava中的實現的Timeout操作符有好幾個變體:

  • timeout(long,TimeUnit): 第一個變體接受一個時長參數,每當原始Observable發射了一項數據,timeout就啓動一個計時器,如果計時器超過了指定指定的時長而原始Observable沒有發射另一項數據,timeout就拋出TimeoutException,以一個錯誤通知終止Observable。 這個timeout默認在computation調度器上執行,你可以通過參數指定其它的調度器。
  • timeout(long,TimeUnit,Observable): 這個版本的timeout在超時時會切換到使用一個你指定的備用的Observable,而不是發錯誤通知。它也默認在computation調度器上執行。
  • timeout(Func1):這個版本的timeout使用一個函數針對原始Observable的每一項返回一個Observable,如果當這個Observable終止時原始Observable還沒有發射另一項數據,就會認爲是超時了,timeout就拋出TimeoutException,以一個錯誤通知終止Observable。
  • timeout(Func1,Observable): 這個版本的timeout同時指定超時時長和備用的Observable。它默認在immediate調度器上執行
  • timeout(Func0,Func1):這個版本的time除了給每一項設置超時,還可以單獨給第一項設置一個超時。它默認在immediate調度器上執行。
  • timeout(Func0,Func1,Observable): 同上,但是同時可以指定一個備用的Observable。它默認在immediate調度器上執行。

示例代碼:

Observable<Integer> obs = Observable.create(new Observable.OnSubscribe<Integer>() {
    @Override
    public void call(Subscriber<? super Integer> subscriber) {
        for (int i = 0; i <= 3; i++) {
            try {
                Thread.sleep(i * 100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            subscriber.onNext(i);
        }
        subscriber.onCompleted();
    }
});

//發射數據時間間隔超過200ms超時
obs.timeout(200, TimeUnit.MILLISECONDS)
        .subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                Log.v(TAG, "onCompleted");
            }
            @Override
            public void onError(Throwable e) {
                Log.v(TAG, "onError:"+e);
            }
            @Override
            public void onNext(Integer integer) {
                Log.v(TAG, "onNext:"+integer);
            }
});

//發射數據時間間隔超過200ms超時,超時後開啓備用Observable
obs.timeout(200, TimeUnit.MILLISECONDS, Observable.just(10,20))
        .subscribe(new Subscriber<Integer>() {
            @Override
            public void onCompleted() {
                Log.v(TAG, "onCompleted");
            }
            @Override
            public void onError(Throwable e) {
                Log.v(TAG, "onError:"+e);
            }
            @Override
            public void onNext(Integer integer) {
                Log.v(TAG, "onNext:"+integer);
            }
        });

輸出:

onNext:0
onNext:1
onError:java.util.concurrent.TimeoutException

onNext:0
onNext:1
onNext:10
onNext:20
onCompleted

7. Timestamp

  它將一個發射T類型數據的Observable轉換爲一個發射類型爲Timestamped的數據的Observable,每一項都包含數據的發射時間。也就是把Observable發射的數據重新包裝了一下,將數據發射的時間打包一起發射出去,這樣觀察者不僅能得到數據,還能得到數據的發射時間。 timestamp默認在immediate調度器上執行,但是可以通過參數指定其它的調度器。

    這裏寫圖片描述

示例代碼:

Observable.just(1,2,3)
        .timestamp()
        .subscribe(new Subscriber<Timestamped<Integer>>() {
            @Override
            public void onCompleted() {
                Log.v(TAG, "onCompleted");
            }
            @Override
            public void onError(Throwable e) {
                Log.v(TAG, "onError:"+e.getMessage());
            }
            @Override
            public void onNext(Timestamped<Integer> integerTimestamped) {
                Log.v(TAG, "onNext:"+integerTimestamped.getValue()+
                        ",time:"+integerTimestamped.getTimestampMillis());
            }
        });

輸出:

onNext:1,time:1465715591222
onNext:2,time:1465715591222
onNext:3,time:1465715591222
onCompleted

8. Using

  Using操作符指示Observable創建一個只在它的生命週期內存在的資源,當Observable終止時這個資源會被自動釋放。
using操作符接受三個參數:

  1. 一個用於 創建一次性資源的工廠函數
  2. 一個用於創建Observable的工廠函數
  3. 一個用於釋放資源的函數

  當一個觀察者訂閱using返回的Observable時,using將會使用Observable工廠函數創建觀察者要觀察的Observable,同時使用資源工廠函數創建一個你想要創建的資源。當觀察者取消訂閱這個Observable時,或者當觀察者終止時(無論是正常終止還是因錯誤而終止),using使用第三個函數釋放它創建的資源。
    這裏寫圖片描述

示例代碼:

class MyObject{
    public void release(){
        Log.v(TAG, "object resource released");
    }
}
/**
 * Using操作符指示Observable創建一個只在它的生命週期內存在的資源,
 * 當Observable終止時這個資源會被自動釋放。
 */
private void op_Using(TextView textView){
    SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
    Observable<Long> obs = Observable.using(
            //一個用於 創建一次性資源的工廠函數
            new Func0<MyObject>() {
                @Override
                public MyObject call() {
                    return new MyObject();
                }
            }
            //一個用於創建Observable的工廠函數,這個函數返回的Observable就是最終被觀察的Observable
            , new Func1<MyObject, Observable<Long>>() {
                @Override
                public Observable<Long> call(MyObject obj) {
                    //創建一個Observable,3s之後發射一個簡單的數字0
                    return Observable.timer(3000,TimeUnit.MILLISECONDS);
                }
            }
            //一個用於釋放資源的函數,當Func2返回的Observable執行完畢之後會被調用
            ,new Action1<MyObject>(){
                @Override
                public void call(MyObject o) {
                   o.release();
                }
            }
    );

    Subscriber subscriber = new Subscriber<Long>() {
        @Override
        public void onCompleted() {
            Log.v(TAG, "onCompleted:" + sdf.format(new Date()));
        }
        @Override
        public void onError(Throwable e) {
            Log.v(TAG, "onError:"+e.getMessage());
        }
        @Override
        public void onNext(Long l) {
            Log.v(TAG, "onNext:"+l);
        }
    };

    Log.v(TAG, "start:" + sdf.format(new Date()));
    obs.subscribe(subscriber);
}

輸出:

start:04:47:26
onNext:0
onCompleted:04:47:29
object resource released

9. To

  將Observable轉換爲另一個對象或數據結構。它們中的一些會阻塞直到Observable終止,然後生成一個等價的對象或數據結構;另一些返回一個發射那個對象或數據結構的Observable。簡而言之就是,將原始Observable轉化爲一個發射另一個對象或者數據結構的Observable,如果原Observable發射完他的數據需要一段時間,使用To操作符得到的Observable將阻塞等待原Observable發射完後再將數據序列打包後發射出去。

    這裏寫圖片描述

RxJava中實現瞭如下幾種To操作符:

  • toList:發射多項數據的Observable會爲每一項數據調用onNext方法,用toList操作符讓Observable將多項數據組合成一個List,然後調用一次onNext方法傳遞整個列表。
    如果原始Observable沒有發射任何數據就調用了onCompleted,toList返回的Observable會在調用onCompleted之前發射一個空列表。如果原始Observable調用了onError,toList返回的Observable會立即調用它的觀察者的onError方法。

  • toMap: toMap收集原始Observable發射的所有數據項到一個Map(默認是HashMap)然後發射這個Map。你可以提供一個用於生成Map的Key的函數,還可以提供一個函數轉換數據項到Map存儲的值(默認數據項本身就是值)。

  • toMultiMap:toMultiMap類似於toMap,不同的是,它生成的這個Map同時還是一個ArrayList(默認是這樣,你可以傳遞一個可選的工廠方法修改這個行爲)。

  • toSortedList:toSortedList類似於toList,不同的是,它會對產生的列表排序,默認是自然升序,如果發射的數據項沒有實現Comparable接口,會拋出一個異常。然而,你也可以傳遞一個函數作爲用於比較兩個數據項,這是toSortedList不會使用Comparable接口。

  • toFuture:toFuture操作符只能用於BlockingObservable(首先必須把原始的Observable轉換爲一個BlockingObservable。可以使用這兩個操作符:BlockingObservable.from或the Observable.toBlocking)。這個操作符將Observable轉換爲一個返回單個數據項的Future,如果原始Observable發射多個數據項,Future會收到一個IllegalArgumentException;如果原始Observable沒有發射任何數據,Future會收到一個NoSuchElementException。
    如果你想將發射多個數據項的Observable轉換爲Future,可以這樣用:myObservable.toList().toBlocking().toFuture()。

  • toIterable:只能用於BlockingObservable。這個操作符將Observable轉換爲一個Iterable,你可以通過它迭代原始Observable發射的數據集。

示例代碼:

SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
//toList:阻塞等待原Observable發射完畢後,將發射的數據轉換成List發射出去
Log.v(TAG, "toList start:" + sdf.format(new Date()));
Observable.interval(1000,TimeUnit.MILLISECONDS)
        .take(3)
        .toList()
        .subscribe(new Subscriber<List<Long>>() {
            @Override
            public void onCompleted() {
                Log.v(TAG, "onCompleted");
            }
            @Override
            public void onError(Throwable e) {
                Log.v(TAG, "onError:" + e.getMessage());
            }
            @Override
            public void onNext(List<Long> longs) {
                Log.v(TAG, "onNext:" + longs+" ->"+ sdf.format(new Date()));
            }
        });

Observable.just(2,4,1,3)
        .delaySubscription(5, TimeUnit.SECONDS)  //延遲5s訂閱
        .toSortedList()
        .subscribe(new Action1<List<Integer>>() {
            @Override
            public void call(List<Integer> integers) {
                Log.v(TAG, "toSortedList onNext:" + integers);
            }
        });

Observable.just(2,4,1,3)
        .delaySubscription(7, TimeUnit.SECONDS)  //延遲5s訂閱
        .toMultimap(new Func1<Integer, String>() {
            //生成map的key
            @Override
            public String call(Integer integer) {
                return integer % 2 == 0 ? "偶" : "奇";
            }
        }, new Func1<Integer, String>() {
            //轉換原始數據項到Map存儲的值(默認數據項本身就是值)
            @Override
            public String call(Integer integer) {
                return integer%2==0?"偶"+integer : "奇"+integer;
            }
        })
        .subscribe(new Action1<Map<String, Collection<String>>>() {
            @Override
            public void call(Map<String, Collection<String>> stringCollectionMap) {
                Collection<String> o = stringCollectionMap.get("偶");
                Collection<String> j = stringCollectionMap.get("奇");
                Log.v(TAG, "toMultimap onNext:" + o);
                Log.v(TAG, "toMultimap onNext:" + j);
            }
        });

輸出:

toList start:08:46:14
onNext:[0, 1, 2] ->08:46:17
onCompleted

toSortedList onNext:[1, 2, 3, 4]

toMultimap onNext:[偶2, 偶4]
toMultimap onNext:[奇1, 奇3]

**有問題請留言,有幫助請點贊(^__^)**

#源碼下載:

https://github.com/openXu/RxJavaTest

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