RxJava 基礎知識
RxJava 學習筆記 -- 過濾操作符
操作符 | 作用 |
---|---|
filter() | 過濾資料 |
takeLast() | 只發射最後的N項資料 |
last() | 只發射最後一項資料 |
lastOrDefault() | 只發射最後一項資料,如果Observable為空,將發射預設值 |
takeLastBuffer() | 將最後的N項資料當做單個資料發射 |
skip() | 跳過開始的N項資料 |
skipLast() | 跳過最後的N項資料 |
take() | 只發射開始的N項資料 |
first() and takeFirst() | 只發射第一項資料,或者滿足某種條件的第一項資料 |
firstOrDefault() | 只發射第一項資料,如果Observable為空,就發射預設值 |
elementAt() | 發射第N項資料 |
elementAtOrDefault() | 發射第N項資料,如果Observable資料少於N項,就發射預設值 |
sample() or throttleLast() | 定期發射Observable最近的資料 |
throttleFirst() | 定期發射Observable發射的第一項資料 |
throttleWithTimeout() or debounce() | 只有當Observable在指定的時間段後還沒有發射資料時,才發射一個資料 |
timeout() | 如果在一個指定的時間段後還沒有發射資料,就發射一個異常 |
distinct() | 過濾掉重複的資料 |
distinctUntilChanged() | 過濾掉連續重複的資料 |
ofType() | 只發射指定型別的資料 |
ignoreElements() | 丟棄所有的正常資料,只發射錯誤或完成通知 |
下面只列舉一些常用的過濾操作符的用法
一. First操作符
只發射第一項(或滿足某個條件的第一項)資料, 如圖:
在RxJava2.x 中,使用first()需要一個預設的Item,對於Observable而言,使用了first()會返回Single型別
fun testFirst(){
Observable.just(1,2,3,4)
.first(2)
.subscribeBy(
onSuccess = {Log.e("TAG",it.toString())},
onError = {Log.e("TAG",it.localizedMessage)}
)
// Observable 不發射任何資料,那麼first操作符的預設值就起作用了
Observable.empty<Int>()
.first(2)
.subscribeBy(
onSuccess = {Log.e("TAG","顯示預設值: "+it.toString())},
onError = {Log.e("TAG",it.localizedMessage)}
)
}
複製程式碼
執行結果
09-10 15:33:55.120 12372-12372/com.mufeng.rxjavademo E/TAG: 1
09-10 15:33:55.122 12372-12372/com.mufeng.rxjavademo E/TAG: 顯示預設值: 2
複製程式碼
二. Last操作符
只發射最後一項(或者滿足某個條件的最後一項)資料, 如圖:
last操作符和first操作符類似,需要一個預設的Item, 也是返回Single型別
fun testLast(){
Observable.just(1,2,3,4)
.last(3)
.subscribeBy(
onSuccess = {Log.e("TAG",it.toString())},
onError = {Log.e("TAG",it.localizedMessage)}
)
// Observable 不發射任何資料,那麼last操作符的預設值就起作用了
Observable.empty<Int>()
.last(2)
.subscribeBy(
onSuccess = {Log.e("TAG","顯示預設值: "+it.toString())},
onError = {Log.e("TAG",it.localizedMessage)}
)
}
複製程式碼
執行結果
09-10 15:41:45.703 12628-12628/com.mufeng.rxjavademo E/TAG: 4
09-10 15:41:45.705 12628-12628/com.mufeng.rxjavademo E/TAG: 顯示預設值: 2
複製程式碼
三. Task操作符
只發射前面的n項資料, 如圖:
簡單用法
fun testTake(){
Observable.just(1,2,3,4,5)
.take(3)
.subscribeBy(
onNext = {Log.e("TAG",it.toString())},
onError = {Log.e("TAG",it.localizedMessage)},
onComplete = {Log.e("TAG","onComplete")}
)
}
複製程式碼
執行結果
09-11 14:50:04.946 13005-13005/com.mufeng.rxjavademo E/TAG: 1
2
09-11 14:50:04.947 13005-13005/com.mufeng.rxjavademo E/TAG: 3
onComplete
複製程式碼
如果Observable發射的資料少於N項,take操作符生成的Observable不會丟擲異常或發射onError通知,仍然會發射出這些資料
示例:
fun testTake(){
Observable.just(1,2,3,4,5)
.take(7)
.subscribeBy(
onNext = {Log.e("TAG",it.toString())},
onError = {Log.e("TAG",it.localizedMessage)},
onComplete = {Log.e("TAG","onComplete")}
)
}
複製程式碼
執行結果
09-11 14:53:17.308 13172-13172/com.mufeng.rxjavademo E/TAG: 1
09-11 14:53:17.309 13172-13172/com.mufeng.rxjavademo E/TAG: 2
3
4
5
onComplete
複製程式碼
四. TakeLast操作符
發射Observable發射的最後N項資料
fun testTakeLast(){
Observable.just(1,2,3,4,5,6)
.takeLast(3)
.subscribeBy(
onNext = {Log.e("TAG",it.toString())},
onError = {Log.e("TAG",it.localizedMessage)},
onComplete = {Log.e("TAG","onComplete")}
)
}
複製程式碼
執行結果
09-11 15:02:47.704 13403-13403/com.mufeng.rxjavademo E/TAG: 4
09-11 15:02:47.705 13403-13403/com.mufeng.rxjavademo E/TAG: 5
6
onComplete
複製程式碼
五. Skip
使用skip操作符,可以忽略Observable發射的前N項資料,只保留之後的資料
fun testSkip(){
Observable.just(1,2,3,4,5,6)
.skip(3)
.subscribeBy(
onNext = {Log.e("TAG",it.toString())},
onError = {Log.e("TAG",it.localizedMessage)},
onComplete = {Log.e("TAG","onComplete")}
)
}
複製程式碼
執行結果
09-11 15:07:06.011 13625-13625/com.mufeng.rxjavademo E/TAG: 4
5
6
onComplete
複製程式碼
六. SkipLast
使用skipLast操作符,可以忽略Observable發射的後N項資料,只發射前面的資料
fun testSkipLast(){
Observable.just(1,2,3,4,5,6)
.skipLast(3)
.subscribeBy(
onNext = {Log.e("TAG",it.toString())},
onError = {Log.e("TAG",it.localizedMessage)},
onComplete = {Log.e("TAG","onComplete")}
)
}
複製程式碼
執行結果
09-11 15:12:57.617 13827-13827/com.mufeng.rxjavademo E/TAG: 1
2
3
onComplete
複製程式碼
七. elementAt
elementAt操作符獲取原始Observable發射的資料序列指定索引位置的資料項,然後當做自己的唯一資料發射
它傳遞一個以0為起始的索引值,發射原始Observable資料序列對應索引位置的值,如果傳遞的值大於原始Observable發射的資料數量,會直接傳送onComplete事件,如果傳遞的是一個負數,則會丟擲"java.lang.IndexOutOfBoundsException: index >= 0 required but it was -1"異常
fun testElementAt(){
Observable.just(1,2,3,4,5,6)
.elementAt(-1)
.subscribeBy(
onSuccess = {Log.e("TAG",it.toString())},
onError = {Log.e("TAG",it.localizedMessage)},
onComplete = {Log.e("TAG","onComplete")}
)
}
複製程式碼
執行結果
09-11 15:21:00.009 14074-14074/com.mufeng.rxjavademo E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.mufeng.rxjavademo, PID: 14074
java.lang.IndexOutOfBoundsException: index >= 0 required but it was -1
at io.reactivex.Observable.elementAt(Observable.java:8105)
...
複製程式碼
八. ignoreElements
ignoreElements操作符忽略原始Observable發射的所有資料,只允許它的終止通知通過,它返回一個Completable型別
九. distinct
distinct 的過濾規則是,只允許沒有發射過的資料項通過
fun testDistince(){
Observable.just(1,2,1,2,3,1)
.distinct()
.subscribeBy(
onNext = {Log.e("TAG",it.toString())},
onError = {Log.e("TAG",it.localizedMessage)},
onComplete = {Log.e("TAG","onComplete")}
)
}
複製程式碼
執行結果
09-11 15:48:30.881 14799-14799/com.mufeng.rxjavademo E/TAG: 1
2
3
onComplete
複製程式碼
distinct還能接受一個Function作為引數,這個函式根據原始Observable發射的資料產生一個key,然後比較這些key而不是資料本身,來判定兩個資料是否不同
與distinct類似的是distinctUntilChanged操作符,該操作符與distinct的區別是,它只判斷一個資料與它的前面的一個相鄰的資料是否不同
十. filter
filter操作符使用你指定的一個謂詞函式測試資料項,只有通過測試的資料才會被髮射
fun testFilter(){
Observable.just(1,2,3,4,5,6)
.filter{it > 3}
.subscribeBy(
onNext = {Log.e("TAG",it.toString())},
onError = {Log.e("TAG",it.localizedMessage)},
onComplete = {Log.e("TAG","onComplete")}
)
}
複製程式碼
執行結果
09-11 15:56:16.980 15032-15032/com.mufeng.rxjavademo E/TAG: 4
09-11 15:56:16.981 15032-15032/com.mufeng.rxjavademo E/TAG: 5
6
onComplete
複製程式碼
十一. throttleFirst
值得一提的是throttleFirst操作符,配合RxBinding使用,可以有效的限制重複點選事件