RxJava2之建立操作符與變換操作符

語言: CN / TW / HK

一起養成寫作習慣!這是我參與「掘金日新計劃 · 4 月更文挑戰」的第2天,點選檢視活動詳情

建立操作符

1.interval

建立一個按固定時間間隔發射整數序列的Observable,相當於定時器。 Observable .interval(3, TimeUnit.SECONDS)//指定時間間隔以及時間的單位 .subscribe(new Consumer<Long>() { @Override public void accept(Long aLong) throws Exception { Log.i(TAG, "accept: "+aLong); } }); 結果為 01-25 14:48:08.920 16172-16199/com.xp.note.rxjava I/RxJavaActivity30: onNext: 31 01-25 14:48:11.919 16172-16199/com.xp.note.rxjava I/RxJavaActivity30: onNext: 32 01-25 14:48:14.920 16172-16199/com.xp.note.rxjava I/RxJavaActivity30: onNext: 33

2.range

建立發射指定範圍的整數序列的Observable,類似於for迴圈,取值範圍左閉右開。 Observable .range(0,3) .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.i(TAG, "accept: "+integer); } }); 結果為 01-25 14:55:39.341 16711-16711/com.xp.note.rxjava I/RxJavaActivity30: accept: 0 01-25 14:55:40.341 16711-16711/com.xp.note.rxjava I/RxJavaActivity30: accept: 1 01-25 14:55:41.343 16711-16711/com.xp.note.rxjava I/RxJavaActivity30: accept: 2

3.repeat

建立一個n次發射重複資料的Observable Observable .range(0,2) .repeat(2)//重複次數 .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.i(TAG, "accept: "+integer); } }); 輸出結果 01-25 15:03:50.446 17017-17017/com.xp.note.rxjava I/RxJavaActivity30: accept: 0 01-25 15:03:50.446 17017-17017/com.xp.note.rxjava I/RxJavaActivity30: accept: 1 01-25 15:03:50.446 17017-17017/com.xp.note.rxjava I/RxJavaActivity30: accept: 0 01-25 15:03:50.446 17017-17017/com.xp.note.rxjava I/RxJavaActivity30: accept: 1

變換操作符

變換操作符的作用是對Observable發射的資料按照一定的規則做一些變換操作,然後將變換的資料發射出去。

1.map

map操作符通過指定一個Function物件,將Observable轉換為一個新的Observable物件然後發射,觀察者將接手新的Observable,然後處理。 Observable.range(0,5).map(new Function<Integer, String>() { @Override public String apply(Integer integer) throws Exception { return "轉換之後:"+integer; } }).subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { Log.i("TAG", "accept: "+s); } }); 輸出結果 ```` 01-29 21:08:25.157 17201-17201/com.xp.note.rxjava I/TAG: accept: 轉換之後:0 01-29 21:08:25.158 17201-17201/com.xp.note.rxjava I/TAG: accept: 轉換之後:1 01-29 21:08:25.158 17201-17201/com.xp.note.rxjava I/TAG: accept: 轉換之後:2 01-29 21:08:25.158 17201-17201/com.xp.note.rxjava I/TAG: accept: 轉換之後:3 01-29 21:08:25.158 17201-17201/com.xp.note.rxjava I/TAG: accept: 轉換之後:4

````

2.flatMap(concatMap)

flatMap將一個Observable變換為多個Observables,然後將他們發射的資料放到一個單獨的Observable 1167421-7728bea372bd612c.png Observable.range(0, 5) .flatMap(new Function<Integer, ObservableSource<String>>() { @Override public ObservableSource<String> apply(Integer integer) throws Exception { return Observable.fromArray(integer + ""); } }).subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { Log.i("TAG", "accept: " + s); } });

concatMap和flatMap的功能是一樣的, 將一個發射資料的Observable變換為多個Observables,然後將它們發射的資料放進一個單獨的Observable。只不過最後合併Observables ,flatMap採用的merge,而concatMap採用的是連線(concat)。總之一句一話,他們的區別在於:concatMap是有序的,flatMap是無序的,concatMap最終輸出的順序與原序列保持一致,而flatMap則不一定,有可能出現交錯。

結果輸出 01-29 22:43:34.796 29345-29469/com.xp.note.rxjava I/TAG: accept: 0 01-29 22:43:34.796 29345-29469/com.xp.note.rxjava I/TAG: accept: 1 01-29 22:43:34.796 29345-29469/com.xp.note.rxjava I/TAG: accept: 2 01-29 22:43:34.796 29345-29469/com.xp.note.rxjava I/TAG: accept: 3 01-29 22:43:34.796 29345-29469/com.xp.note.rxjava I/TAG: accept: 4

map適用於一對一轉換,當然也可以配合flatmap進行適用 flatmap適用於一對多,多對多的場景

flatmap可用於化解迴圈巢狀,還有一種場景就是連續請求兩個介面,第一個介面的返回值是第二個介面的請求引數,在這種情況下,以前我們會在一個請求完成後,在onResponse中獲取結果再請求另一個介面。這種介面巢狀,程式碼看起來是非常醜陋的,運用flatMap就能很好的解決這個問題。程式碼看起來非常優雅而且邏輯清晰。如果需要保證順序的話,使用concatMap

更多操作符

3.buffer

buffer將原來的Observable轉化為新的Observable,這個新的Observable每次發射一組列表值,而不是一個一個地發射。

aaa8dc.jpg Observable.range(0, 7) .buffer(3) .subscribe(new Consumer<List<Integer>>() {//引數是List而不是Integer,說明發射了一組 @Override public void accept(List<Integer> integers) throws Exception { Log.i("TAG", "accept: " + integers.size()); } }); 結果輸出 04-19 22:00:12.901 11686-11686/com.xp.note.rxjava I/TAG: accept: 3 04-19 22:00:12.902 11686-11686/com.xp.note.rxjava I/TAG: accept: 3 04-19 22:00:12.902 11686-11686/com.xp.note.rxjava I/TAG: accept: 1

4.groupBy

groupBy將原始的Observable拆分成一些Observables集合,這些集合中的每一個都發射原始Observable的一個子序列,哪個資料項由哪一個Observable發射是由一個函式判定的,這個函式給每一項指定一個Key,Key相同的資料會被同一個Observable發射。 iamge ``` User user1 = new User("張三丰",100); User user2 = new User("張翠山",30); User user3 = new User("張無極",18); User user4 = new User("珠兒",15); User user5 = new User("周芷若",16); User user6 = new User("小昭",15); User user7 = new User("白眉鷹王",100);

Observable<GroupedObservable<Integer,User>> obs = Observable.just(user1, user2, user3, user4, user5, user6, user7)
        .groupBy(new Function<User, Integer>() {
    @Override
    public Integer apply(User user) throws Exception {
        return user.getAge();
    }
});
Observable.concat(obs).subscribe(new Consumer<User>() {
    @Override
    public void accept(User user) throws Exception {
        Log.i("TAG", "accept: "+user.toString());
    }
});

結果輸出 04-19 22:00:12.950 11686-11686/com.xp.note.rxjava I/TAG: accept: 張三丰 100歲 04-19 22:00:12.951 11686-11686/com.xp.note.rxjava I/TAG: accept: 白眉鷹王 100歲 04-19 22:00:12.953 11686-11686/com.xp.note.rxjava I/TAG: accept: 張翠山 30歲 04-19 22:00:12.953 11686-11686/com.xp.note.rxjava I/TAG: accept: 張無極 18歲 04-19 22:00:12.954 11686-11686/com.xp.note.rxjava I/TAG: accept: 珠兒 15歲 04-19 22:00:12.954 11686-11686/com.xp.note.rxjava I/TAG: accept: 小昭 15歲 04-19 22:00:12.954 11686-11686/com.xp.note.rxjava I/TAG: accept: 周芷若 16歲

```