本文中通過圖解的方式解釋Rxjava中複雜的操作符,值得收藏。其中用到的demo地址:RxJava2-Android-Samples
1. buffer
demo:
Observable<List<String>> buffered = getObservable().buffer(2, 3);
第一個參數列示在emit資料之前,Observable需要快取多少個資料
第二個參數列示每次emit資料之後跳過幾個資料。
圖示中就是每次buffer 2個資料之後emit,每次emit之後跳過3個資料。
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。
4. defer
defer為每一個observer建立一個ObservableSource,這樣當第一個observer訂閱之後如果ObservableSource中的資料發生變化,第二個訂閱的Observer會得到不同的資料。
demo:
Observable.defer(new Callable<ObservableSource<? extends String>>() {
@Override
public ObservableSource<? extends String> call() throws Exception {
return Observable.just(brand);
}
});複製程式碼
demo中可以隨時改變brand
的值,這樣不同的Observer可能會得到不同的值。
5. distinct
distinct可以對 emit 的資料做去重處理
demo:
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:
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中原始資料中奇數會被過濾掉。
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…