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使用,可以有效的限制重复点击事件