通过上篇的学习,我们知道了如何去转换一个Observable对象成我们想要的格式,但是我们想直接省去if else而拿到想要的数据,这个怎么做呢?那么我们就在这篇文章里来系统的学习一下吧
Observable.create(new Observable.OnSubscribe() {
@Override
public void call(Subscriber super Integer> subscriber) {
for (int i=0;i<10;i++) {
subscriber.onNext(i);
int time=100;
if (i%3==0) {
time=400;
}
try {
Thread.sleep(time);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
subscriber.onCompleted();
}
//过滤掉不足300ms的
}).debounce(300, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1() {
@Override
public void call(Integer integer) {
Log.d("SampleFilteringActivity", "integer:" + integer);
}
});
运行结果
com.renyu.rxdemo D/SampleFilteringActivity: integer:0
com.renyu.rxdemo D/SampleFilteringActivity: integer:3
com.renyu.rxdemo D/SampleFilteringActivity: integer:6
com.renyu.rxdemo D/SampleFilteringActivity: integer:9
debounce操作符是在源Observable发射之后,在规定的时间内没有别的结果产生,则把这个结果提交给订阅者。由于最后一条数据没有其他数据覆盖,所以订阅者都可以收到
除了在时间范畴上进行控制,还可以根据函数来限流
Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 10, 11).debounce(new Func1>() {
@Override
public Observable call(final Integer integer) {
return Observable.create(new Observable.OnSubscribe() {
@Override
public void call(Subscriber super String> subscriber) {
if (integer%4==0) {
subscriber.onCompleted();
}
}
});
}
}).subscribe(new Action1() {
@Override
public void call(Integer integer) {
Log.d("SampleFilteringActivity", "integer:" + integer);
}
});
运行结果
com.renyu.rxdemo D/SampleFilteringActivity: integer:4
com.renyu.rxdemo D/SampleFilteringActivity: integer:8
com.renyu.rxdemo D/SampleFilteringActivity: integer:11
只要能被4整除,订阅者就可以收到。最后一个值情况例外
throttleWithTimeout在时间限流上功能跟debounce一致
Observable.just(1, 2, 4, 1, 3, 5).distinct().subscribe(new Action1() {
@Override
public void call(Integer integer) {
Log.d("SampleFilteringActivity", "integer:" + integer);
}
});
运行结果
com.renyu.rxdemo D/SampleFilteringActivity: integer:1
com.renyu.rxdemo D/SampleFilteringActivity: integer:2
com.renyu.rxdemo D/SampleFilteringActivity: integer:4
com.renyu.rxdemo D/SampleFilteringActivity: integer:3
com.renyu.rxdemo D/SampleFilteringActivity: integer:5
功能就是去重
如果是distinctUntilChangedObserver
,他不是完全过滤,只是连续N个相同的数据,仅仅保留一个,后面的他就不管了
,例如
Observable.just(1, 2, 3, 3, 3, 1, 2, 3, 3).distinctUntilChanged().subscribe(new Action1() {
@Override
public void call(Integer integer) {
Log.d("SampleFilteringActivity", "integer:" + integer);
}
});
运行结果
com.renyu.rxdemo D/SampleFilteringActivity: integer:1
com.renyu.rxdemo D/SampleFilteringActivity: integer:2
com.renyu.rxdemo D/SampleFilteringActivity: integer:3
com.renyu.rxdemo D/SampleFilteringActivity: integer:1
com.renyu.rxdemo D/SampleFilteringActivity: integer:2
com.renyu.rxdemo D/SampleFilteringActivity: integer:3
下面介绍多点功能差不多的操作符:
skipLast
这里简单说明下
elementAt是只发射第N个元素
,
take是只发射前面N个元素
,
first是只发射第一个元素,等同于elementAt(0)
,
last是只发射最后一个元素
,
takeFirst类似于take,也类似于first,也是只发射前面N个元素。他和take的区别在于如果Observable没有发射数据,take会抛出NoSuchElementException异常,而takeFirst不会,他会产生一个没有onNext只有onCompleted的空Observable
,
takeLast是只发射最后N个元素
skip是跳过之前skip个元素,直接返回后面的所有元素
skipLast是跳过最后的几个元素,直接返回之前的所有元素
Filter操作符
Observable.just(1, 2, 4, 1, 3, 5).filter(new Func1() {
@Override
public Boolean call(Integer integer) {
return integer>3;
}
}).subscribe(new Action1() {
@Override
public void call(Integer integer) {
Log.d("SampleFilteringActivity", "integer:" + integer);
}
});
运行结果
com.renyu.rxdemo D/SampleFilteringActivity: integer:4
com.renyu.rxdemo D/SampleFilteringActivity: integer:5
对源Observable发射出来的数据按照一定条件进行过滤
Observable.just("1", 2, 3.0).ofType(String.class).subscribe(new Action1() {
@Override
public void call(String s) {
Log.d("SampleFilteringActivity", s);
}
});
运行结果
com.renyu.rxdemo D/SampleFilteringActivity: 1
类似于filter但是又不同,他是按照数据类型进行过滤
,此处就是找出String类型的发射结果
Observable.just(1, 2, 4, 1, 3, 5).single(new Func1() {
@Override
public Boolean call(Integer integer) {
//取大于4的唯一一个元素,否则抛出异常
return integer>=5;
}
}).subscribe(new Subscriber() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
e.printStackTrace();
}
@Override
public void onNext(Integer integer) {
Log.d("SampleFilteringActivity", "integer:" + integer);
}
});
运行结果
com.renyu.rxdemo D/SampleFilteringActivity: integer:5
同样是对源Observable发射出的数据进行判断,如果返回的过滤结果数量不是1,他就抛java.lang.IllegalArgumentException: Sequence contains too many elements
ignoreElements
忽略掉所有的返回结果,仅仅保留onError和onCompleted
Sample
Observable.create(new Observable.OnSubscribe() {
@Override
public void call(Subscriber super String> subscriber) {
for (int i=0;i<10;i++) {
subscriber.onNext(""+i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).sample(2800, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread()).subscribe(new Action1() {
@Override
public void call(String s) {
Log.d("SampleFilteringActivity", s);
}
});
运行结果
com.renyu.rxdemo D/SampleFilteringActivity: 2
com.renyu.rxdemo D/SampleFilteringActivity: 5
com.renyu.rxdemo D/SampleFilteringActivity: 8
com.renyu.rxdemo D/SampleFilteringActivity: 9
sample是按照指定的时间间隔去定时扫描Observable发射出的最后一条数据
,通过下图来说明
2.2s的时候正好数据2发射完成,4.4s的时候数据5完成,以此类推,最后一条数据9发出之后没有发生改变,直到8.8s被调用显示