您好,欢迎访问一九零五行业门户网

RxJava操作符(三)Filtering_PHP教程

rxjava操作符(三)filtering在上一篇文章里,我们了解了转化操作符,能将数据转化为我们想要的格式,但是如果数据集合里面有一些我们想要过滤掉的数据怎么办?这时候我们就需要使用过滤操作符了,有点类似于sql里的where,让observable只返回满足我们条件的数据。
一、debounce
debounce操作符就是起到了限流的作用,可以理解为阀门,当你半开阀门的时候,水会以较慢的速度流出来。不同之处就是阀门里的水不会浪费掉,而debounce过滤掉的数据会被丢弃掉。在rxjava中,将这个操作符氛围了throttlewithtimeout和debounce两个操作符。先来看一下throttlewithtimeout吧,如下图所示,这个操作符通过时间来限流,源observable每次发射出来一个数据后就会进行计时,如果在设定好的时间结束前源observable有新的数据发射出来,这个数据就会被丢弃,同时重新开始计时。如果每次都是在计时结束前发射数据,那么这个限流就会走向极端:只会发射最后一个数据。
首先我们来创建一个observable,每隔100毫秒发射一个数据,当要发射的数据是3的倍数的时候,下一个数据就延迟到300毫秒再发射。
private observable createobserver() {
return observable.create(new observable.onsubscribe() {
@override
public void call(subscriber subscriber) {
for (int i = 0; i throttlewithtimeoutobserver().subscribe(i -> log(throttlewithtimeout: + i)));
运行结果如下,可以看到,不是3的倍数的数据在发射后200毫秒内会发射出新的数据,所以会被过滤掉。
debounce操作符也可以使用时间来进行过滤,这时它跟throttlewithtimeout使用起来是一样,但是deounce操作符还可以根据一个函数来进行限流。这个函数的返回值是一个临时observable,如果源observable在发射一个新的数据的时候,上一个数据根据函数所生成的临时observable还没有结束,那么上一个数据就会被过滤掉。
生成一个observable并使用debounce对其进行过滤,只有发射来的数据为偶数的时候才会调用oncompleted方法来表示这个临时的observable已经终止。
private observable debounceobserver() {
return observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9).debounce(integer -> {
log(integer);
return observable.create(new observable.onsubscribe() {
@override
public void call(subscriber subscriber) {
if (integer % 2 == 0 && !subscriber.isunsubscribed()) {
log(complete: + integer);
subscriber.onnext(integer);
subscriber.oncompleted();
}
}
});
})
.observeon(androidschedulers.mainthread());
}
对其进行订阅
mrbutton.setonclicklistener(e -> debounceobserver().subscribe(i -> log(debounce: + i)));
运行结果如下,可以看到,只有那些调用了oncompleted方法的数据才会被发射出来,其他的都过滤掉了。
二、distinct
distinct操作符的用处就是用来去重,非常好理解。如下图所示,所有重复的数据都会被过滤掉。还有一个操作符distinctuntilchanged,是用来过滤掉连续的重复数据。
创建两个observable,并使用distinct和distinctutilchanged操作符分别对其进行过滤
private observable distinctobserver() {
return observable.just(1, 2, 3, 4, 5, 4, 3, 2, 1).distinct();
}
private observable distinctuntilchangedobserver() {
return observable.just(1, 2, 3, 3, 3, 1, 2, 3, 3).distinctuntilchanged();
}
进行订阅
mlbutton.settext(distinct);
mlbutton.setonclicklistener(e -> distinctobserver().subscribe(i -> log(distinct: + i)));
mrbutton.settext(untilchanged);
mrbutton.setonclicklistener(e -> distinctuntilchangedobserver().subscribe(i -> log(untilchanged: + i)));
运行结果如下所示,可以看到distinct过滤掉了所有重复的数字,二distinctutilchanged只过滤掉重复的数字
三、elementat、filter
这两个操作符都很好理解,elementat只会返回指定位置的数据,而filter只会返回满足过滤条件的数据,其示意图分别如下所示
创建两个observable对象并分别使用elementat和filter操作符对其进行过滤
private observable elementatobserver() {
return observable.just(0, 1, 2, 3, 4, 5).elementat(2);
}
private observable filterobserver() {
return observable.just(0, 1, 2, 3, 4, 5).filter(i -> i elementatobserver().subscribe(i -> log(elementat: + i)));
mrbutton.settext(filter);
mrbutton.setonclicklistener(e -> filterobserver().subscribe(i -> log(filter: + i)));
运行结果如下
四、first、last
first操作符只会返回第一条数据,并且还可以返回满足条件的第一条数据。如果你看过我以前的博客,就会发现在我们使用rxjava实现三级缓存的例子里,就是使用first操作符来选择所要使用的缓存。与first相反,last操作符只返回最后一条满足条件的数据。
另外还有一个blockingobservable方法,这个方法不会对observable做任何处理,只会阻塞住,当满足条件的数据发射出来的时候才会返回一个blockingobservable对象。可以使用observable.toblocking或者blockingobservable.from方法来将一个observable对象转化为blockingobservable对象。blockingobservable可以和first操作符进行配合使用。
创建两个observable对象并分别使用first操作符进行处理
private observable firstobserver() {
return observable.just(0, 1, 2, 3, 4, 5).first(i -> i > 1);
}
private blockingobservable filterobserver() {
return observable.create(new observable.onsubscribe() {
@override
public void call(subscriber subscriber) {
for (int i = 0; i firstobserver().subscribe(i -> log(first: + i)));
mrbutton.settext( blocking);
mrbutton.setonclicklistener(e -> {
log(blocking: + filterobserver().first(i -> i > 1));
});
运行结果如下。可以看到first操作符返回了第一个大于1的数2,而blockingobservable则一直阻塞着,直到第一个大于1的数据发射出来。
五、skip、take
skip操作符将源observable发射的数据过滤掉前n项,而take操作符则只取前n项,理解和使用起来都很容易,但是用处很大。另外还有skiplast和takelast操作符,分别是从后面进行过滤操作。
创建两个observable并分别使用skip和take操作符对其进行过滤操作
private observable skipobserver() {
return observable.just(0, 1, 2, 3, 4, 5).skip(2);
}
private observable takeobserver() {
return observable.just(0, 1, 2, 3, 4, 5).take(2);
}
分别进行订阅
mlbutton.settext(skip);
mlbutton.setonclicklistener(e -> skipobserver().subscribe(i -> log(skip: + i)));
mrbutton.settext(take);
mrbutton.setonclicklistener(e -> takeobserver().subscribe(i -> log(take: + i)));
运行结果如下,可以看到skip过滤掉了前两项,而take则过滤掉了除了前两项的其他所有项。
六、sample、throttlefirst
sample操作符会定时地发射源observable最近发射的数据,其他的都会被过滤掉,等效于throttlelast操作符,而throttlefirst操作符则会定期发射这个时间段里源observable发射的第一个数据
我们创建一个observable每隔200毫秒发射一个数据,然后分别使用sample和throttlefirst操作符对其进行过滤
private observable sampleobserver() {
return createobserver().sample(1000, timeunit.milliseconds);
}
private observable throttlefirstobserver() {
return createobserver().throttlefirst(1000, timeunit.milliseconds);
}
private observable createobserver() {
return observable.create(new observable.onsubscribe() {
@override
public void call(subscriber subscriber) {
for (int i = 0; i sampleobserver().subscribe(i -> log(sample: + i)));
mrbutton.settext(throttlefirst);
mrbutton.setonclicklistener(e -> throttlefirstobserver().subscribe(i -> log(throttlefirst: + i)));
运行结果如下,可以看到sample操作符会每隔5个数字发射出一个数据来,而throttlefirst则会每隔5个数据发射第一个数据。
本文的demo程序见github:https://github.com/chaoba/rxjavademo
http://www.bkjia.com/phpjc/1077810.htmlwww.bkjia.comtruehttp://www.bkjia.com/phpjc/1077810.htmltecharticlerxjava操作符(三)filtering 在上一篇文章里,我们了解了转化操作符,能将数据转化为我们想要的格式,但是如果数据集合里面有一些我们想...
其它类似信息

推荐信息