Rxjava2操作符(二)

android大哥發表於2017-12-12

友情連結:
Rxjava操作符2(一)
Rxjava操作符2(二)
Rxjava操作符2(三)
demo地址:github

轉化型

Map 對Observable發射的每一項資料都用一個函式來進行轉換。

例項: 發射過來的數乘以2

 Observable.just(1, 2, 3, 4).map(new Function<Integer, Integer>() {
                    @Override
                    public Integer apply(Integer integer) throws Exception {
                        return integer * 2;
                    }
                }).subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer s) throws Exception {
                        Log.i(TAG, "map:" + s);
                    }
                });
複製程式碼

列印的是:

12-11 06:16:30.758 2284-2284/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: map:2
12-11 06:16:30.758 2284-2284/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: map:4
12-11 06:16:30.758 2284-2284/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: map:6
12-11 06:16:30.758 2284-2284/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: map:8
複製程式碼

FlatMap 建立多個Observable

將一個傳送事件的上游Observable變換為多個傳送事件的Observables,然後將它們發射的事件合併後放進一個單獨的Observable裡.如果要保證順序的話,可以使用concatMap。
例項:把傳送過來資料都變成發射一個集合的Observable

  • 應用場景:使用者註冊成功後需要自動登入 先呼叫註冊介面,成功後在呼叫登入介面
 Observable.just(1, 2, 3, 4).flatMap(new Function<Integer, Observable<Integer>>() {
                    @Override
                    public Observable<Integer> apply(Integer integer) throws Exception {
                        ArrayList<Integer> integers = new ArrayList<>();
                        for (int i = 0; i < 3; i++) {
                            integers.add(i);
                        }
                        return Observable.fromIterable(integers);
                    }
                }).subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer s) throws Exception {
                        Log.i(TAG, "flatMap:" + s);
                    }
                });
複製程式碼

列印的是:

12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:0
12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:1
12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:2
12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:0
12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:1
12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:2
12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:0
12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:1
12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:2
12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:0
12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:1
12-11 06:20:12.486 3617-3617/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: flatMap:2
複製程式碼

buffer(long count, long skip) 把傳送過來的資料收整合一個集合, 然後傳送一個集合給下游

count:表示一個集合中可以收集幾個資料 skip:表示每隔第幾個Observable 傳送過來的 開始收集資料 例項: 通過下面的例項可以更好的理解

Observable.just(1, 2, 3,4,5,6,7,8,9).buffer(4,2).subscribe(new Consumer<List<Integer>>() {
                    @Override
                    public void accept(List<Integer> integers) throws Exception {
                        Log.i(TAG, "buffer:" + integers);
                    }
                });
複製程式碼

列印出來:

12-11 06:46:29.283 5994-5994/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: buffer:[1, 2, 3, 4]
12-11 06:46:29.283 5994-5994/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: buffer:[3, 4, 5, 6]
12-11 06:46:29.283 5994-5994/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: buffer:[5, 6, 7, 8]
12-11 06:46:29.283 5994-5994/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: buffer:[7, 8, 9]
12-11 06:46:29.283 5994-5994/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: buffer:[9]
複製程式碼

window(long count, long skip) 類似於buffer快取一個list集合,區別在於window將這個結果集合封裝成了observable

例項:

 Observable.just(1, 2, 3,4,5,6,7,8,9).window(2, 3).subscribe(new Consumer<Observable<Integer>>() {
                    @Override
                    public void accept(Observable<Integer> integerObservable) throws Exception {
                        Log.i(TAG, "window:" + integerObservable);
                        integerObservable.subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.i(TAG, "window:" + integer);

                            }
                        });
                    }
                });
複製程式碼

列印結果:

-11 07:01:12.387 7191-7191/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: window:io.reactivex.subjects.UnicastSubject@f87e3b7
12-11 07:01:12.387 7191-7191/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: window:1
12-11 07:01:12.387 7191-7191/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: window:2
12-11 07:01:12.387 7191-7191/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: window:io.reactivex.subjects.UnicastSubject@ac7e724
12-11 07:01:12.387 7191-7191/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: window:4
12-11 07:01:12.387 7191-7191/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: window:5
12-11 07:01:12.387 7191-7191/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: window:io.reactivex.subjects.UnicastSubject@962928d
12-11 07:01:12.388 7191-7191/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: window:7
12-11 07:01:12.388 7191-7191/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: window:8
複製程式碼

groupBy 將Observable分拆為Observable集合,將原始Observable發射的資料按Key分組,每一個Observable發射一組不同的資料。

 Observable.just(1, 2, 3,4,5).groupBy(new Function<Integer, String>() {
                    @Override
                    public String apply(Integer integer) throws Exception {
                        return integer%2==0?"偶數":"奇數";
                    }
                }).subscribe(new Consumer<GroupedObservable<String, Integer>>() {
                    @Override
                    public void accept(final GroupedObservable<String, Integer> stringIntegerGroupedObservable) throws Exception {
                        stringIntegerGroupedObservable.subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.i(TAG, "groupby:" +stringIntegerGroupedObservable.getKey()+"----"+ integer);
                            }
                        });
                    }
                });
複製程式碼

列印結果:

2-11 07:35:40.544 8600-8600/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: groupby:奇數----1
12-11 07:35:40.544 8600-8600/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: groupby:偶數----2
12-11 07:35:40.544 8600-8600/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: groupby:奇數----3
12-11 07:35:40.544 8600-8600/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: groupby:偶數----4
12-11 07:35:40.544 8600-8600/niezhiyang.cn.rxjava2_android_samples I/TransformingActivity: groupby:奇數----5
複製程式碼

過濾型

filter 最基本的過濾

例項: 過濾大於發射過來大於2的資料Observable

 Observable.just(1, 2, 3, 4, 5, 6)
                        .filter(new Predicate<Integer>() {
                            @Override
                            public boolean test(Integer integer) throws Exception {
                                return integer > 2;
                            }
                        })
                        .subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.i(TAG, "filter--大於2的資料有:" + integer);
                            }
                        });

複製程式碼

列印出來:

12-11 09:15:58.329 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: filter--大於2的資料有:3
12-11 09:15:58.329 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: filter--大於2的資料有:4
12-11 09:15:58.329 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: filter--大於2的資料有:5
12-11 09:15:58.329 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: filter--大於2的資料有:6
複製程式碼

distince 去除重複的Observable

例項:

  Observable.just(1, 1, 3, 3, 5, 6)
                        .distinct()
                        .subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.i(TAG, "distinct--去除重複的資料:" + integer);
                            }
                        });
複製程式碼

列印出來:

12-11 09:17:10.046 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: distinct--去除重複的資料:1
12-11 09:17:10.046 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: distinct--去除重複的資料:3
12-11 09:17:10.046 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: distinct--去除重複的資料:5
12-11 09:17:10.046 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: distinct--去除重複的資料:6
複製程式碼

distince 去除重複的Observable

例項:

  Observable.just(1, 1, 3, 3, 5, 6)
                        .distinct()
                        .subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.i(TAG, "distinct--去除重複的資料:" + integer);
                            }
                        });
複製程式碼

列印出來:

12-11 09:17:10.046 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: distinct--去除重複的資料:1
12-11 09:17:10.046 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: distinct--去除重複的資料:3
12-11 09:17:10.046 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: distinct--去除重複的資料:5
12-11 09:17:10.046 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: distinct--去除重複的資料:6
複製程式碼

skip 跳過前幾個資料的Observable

例項: 跳過前兩個

 Observable.just(1, 2, 3, 4, 5, 6)
                        .skip(2)
                        .subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.i(TAG, "skip--跳過的資料:" + integer);
                            }
                        });
複製程式碼

列印出來:

12-11 09:17:37.919 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: skip--跳過的資料:3
12-11 09:17:37.919 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: skip--跳過的資料:4
12-11 09:17:37.919 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: skip--跳過的資料:5
12-11 09:17:37.919 12569-12569/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: skip--跳過的資料:6
複製程式碼

take 只發射前幾個陣列的Observable

例項: 發射前兩個

  Observable.just(1, 2, 3, 4, 5, 6)
                        .take(2)
//                        .take(1000, TimeUnit.MICROSECONDS)
                        .subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.i(TAG, "take--發射的前兩個資料:" + integer);
                            }
                        });
複製程式碼

列印出來:

12-11 09:22:08.607 13137-13137/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: take--發射的前兩個資料:1
12-11 09:22:08.607 13137-13137/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: take--發射的前兩個資料:2
複製程式碼

過載 take(1000, TimeUnit.MICROSECONDS) 至發射前1000ms的資料

last 只發射最後一項(或者滿足某個條件的最後一項)資料,可以指定預設值。

例項: 發射前兩個

Observable.just(1, 2, 3, 4, 5, 6)
                        .last(3)
                        .subscribe(new Consumer<Integer>() {
                            @Override
                            public void accept(Integer integer) throws Exception {
                                Log.i(TAG, "last--最後的資料:" + integer);
                            }
                        });
複製程式碼

列印出來:

12-11 09:26:11.404 13510-13510/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: last--最後的資料:6
複製程式碼

debounce 如果兩次資料的發射間隔小於指定時間,就會丟棄前一次的資料。

  • 使用場景一: 搜尋框搜尋的時候,比如搜尋"我的"的時候,輸入"我"會搜出來內容,之後有打了個"的"字,這下就變成"我的"的搜尋來的內容了,用這個操作符完全可以解決
  Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                        emitter.onNext(1);
                        emitter.onNext(2);
                        emitter.onNext(3);
                        emitter.onNext(4);
                        emitter.onNext(5);
                        Thread.sleep(2000);
                        emitter.onNext(6);
                        emitter.onNext(7);
                        emitter.onComplete();
                    }
                }).debounce(1000, TimeUnit.MICROSECONDS).subscribeOn(Schedulers.io()).subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "debounce--:" + integer);
                    }
                });
複製程式碼

列印出來:

12-11 09:33:30.191 14526-14561/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: debounce--:5
12-11 09:33:32.191 14526-14560/niezhiyang.cn.rxjava2_android_samples I/FilteringActivity: debounce--:7
複製程式碼

組合型

zip 通過一個函式將多個Observable傳送的事件結合到一起,然後傳送這些組合到一起的事件. 它按照嚴格的順序應用這個函式。它只發射與發射資料項最少的那個Observable一樣多的資料。

  • 使用場景: 實現多個介面資料共同更新 UI
 Observable<Integer> observable1 = Observable.just(1, 2, 3, 4);
                Observable<Integer> observable2 = Observable.just(1, 2, 3);
                Observable.zip(observable1, observable2, new BiFunction<Integer, Integer, String>() {
                    @Override
                    public String apply(Integer integer, Integer integer2) throws Exception {
                        return integer + integer2 + "";
                    }
                }).subscribe(new Consumer<String>() {

                    @Override
                    public void accept(String s) throws Exception {
                        Log.i(TAG, "zip合併後的資料是:" + s);
                    }
                });
複製程式碼

列印出來的是:

12-12 03:38:43.695 2328-2328/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: zip合併後的資料是:2
12-12 03:38:43.695 2328-2328/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: zip合併後的資料是:4
12-12 03:38:43.695 2328-2328/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: zip合併後的資料是:6
複製程式碼

concat 是接收若干個Observables,發射資料是有序的,不會交叉 , 如果第一個傳送onNext的話就不會走第二個Observable,如果第一個傳送的是onComplete那麼就走第二個Observable

  • 使用場景一: 當請求資料的時候,如果有快取的話先從快取中讀取,如果快取沒有的話在從網路讀取
  • 使用場景二: 當請求網路資料的時候,如果網路資料有錯誤的話,就展示快取的資料
 Observable<Integer> observable3 = Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        if (true) {
                        //假如有快取就走這裡
                            e.onNext(1);
                        } else {
                         //假如沒有快取就走這裡
                            e.onComplete();
                        }

                    }
                });
                Observable<Integer> observable4 = Observable.just(1, 2, 3);
                Observable.concat(observable3, observable4).subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "concat的資料是:" + integer);
                    }
                });
複製程式碼

列印出來的是:

12-12 03:50:37.258 4663-4663/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: concat的資料是:1
複製程式碼

merge 將多個Observable合併為一個。不同於concat,merge不是按照新增順序連線,而是按照時間線來連線。把多個被觀察者合併到一個被觀察者身上一起輸出,但是可能會讓合併的被觀察者發射的資料交錯

 Observable<Integer> observable3 = Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                        if (true) {
                            e.onNext(1);
                        } else {
                            e.onComplete();
                        }

                    }
                });
                Observable<Integer> observable4 = Observable.just(1, 2, 3);
                Observable.concat(observable3, observable4).subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "concat的資料是:" + integer);
                    }
                });
複製程式碼

列印出來的是:

12-12 05:09:03.431 7528-7558/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: merge合併後的資料是:4
12-12 05:09:03.431 7528-7558/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: merge合併後的資料是:1
12-12 05:09:03.431 7528-7558/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: merge合併後的資料是:2
12-12 05:09:03.431 7528-7558/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: merge合併後的資料是:3
12-12 05:09:03.431 7528-7558/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: merge合併後的資料是:5
12-12 05:09:03.431 7528-7558/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: merge合併後的資料是:6
複製程式碼

combineLatest用來將多個Observable發射的資料組裝起來然後在發射

  • 使用場景一: 來做Android表單的校驗 ,比如所有的資料不為空的時候,設定提交按鈕可以點選
 Observable<Integer> observable7 = Observable.just(1, 2, 3);
                Observable<Integer> observable8 = Observable.just(4, 5, 6, 7);
                Observable.combineLatest(observable7, observable8, new BiFunction<Integer, Integer, Integer>() {
                    @Override
                    public Integer apply(Integer integer, Integer integer2) throws Exception {
                        //integer 這個就是observable7中最後發的一個元素
                        return integer+integer2;
                    }
                }).subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "combineLatest的資料是:" + integer);
                    }
                });
複製程式碼

列印出來的是:

12-12 05:17:00.774 8427-8427/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: combineLatest的資料是:7
12-12 05:17:00.774 8427-8427/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: combineLatest的資料是:8
12-12 05:17:00.774 8427-8427/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: combineLatest的資料是:9
12-12 05:17:00.774 8427-8427/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: combineLatest的資料是:10
複製程式碼

startWith增加一點同型別的資料

 Observable.just(1, 2, 3).startWith(0).subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.i(TAG, "startWith新增後的資料是:" + integer);
                    }
                });
複製程式碼

列印出來的是:

12-12 05:17:54.255 8427-8427/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: startWith新增後的資料是:0
12-12 05:17:54.255 8427-8427/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: startWith新增後的資料是:1
12-12 05:17:54.255 8427-8427/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: startWith新增後的資料是:2
12-12 05:17:54.255 8427-8427/niezhiyang.cn.rxjava2_android_samples I/CombiningActivity: startWith新增後的資料是:3
複製程式碼

相關文章