RxJava中的过滤操作符,顾名思义,这类操作符主要用于对事件数据的筛选过滤,只返回满足我们条件的数据。
我们试想一下这样的一个需求,有一个学生集合,要求将其中成绩不及格的学生过滤,返回成绩合格的学生集合,如果平时一般会怎么做呢?可能会这样实现:
List<Student> newList = new ArrayList<>();
for (int i = 0; i < oldList.size(); i++) {
if(oldList.get(i).getCore()>60){
newList.add(oldList.get(i));
}
}
对于极度厌恶多层嵌套结构的我来说,实在不喜欢这样的代码。这样的思路,会随着业务逻辑的复杂程度,变得越来越复杂。
还好有RxJava,之后的代码着实简化了许多。
RxJava过滤类操作符主要包含:
Filter、Take、TakeLast、TakeUntil、Skip、SkipLast、ElementAt、Debounce、Distinct、DistinctUntilChanged、First、Last等等。
先定义这样一个数据集合:
List<Person> list = new ArrayList<>();
for (int i = 0; i < 20; i++) {
list.add(new Person(i, "js" + i));
}
filter(Func1)用来过滤观测序列中我们不想要的值,只返回满足条件的值。
filter传入Func1对象,第一个泛型是传入的发射类型,第二个参数是boolean类型,表示是否过滤。
Observable.from(list)
.filter(new Func1<Person, Boolean>() {
@Override
public Boolean call(Person person) {
return person.getAge() > 10;
}
})
.subscribe(new Action1<Person>() {
@Override
public void call(Person person) {
Log.e("filter", "call: " + person.toString());
}
});
take方法,传入一整数n,表示只取前n个数据。
Observable.from(list)
.take(3)
.subscribe(new Action1<Person>() {
@Override
public void call(Person person) {
Log.e("take", "call: " + person);
}
});
takeLast(int)同样用一个整数n作为参数,只不过它发射的是观测序列中后n个元素。
Observable.from(list)
.takeLast(3)
.subscribe(new Action1<Person>() {
@Override
public void call(Person person) {
Log.e("take", "call: " + person);
}
});
skip(int)让我们可以忽略Observable发射的前n项数据。
Observable.from(list)
.skip(3)
.subscribe(new Action1<Person>() {
@Override
public void call(Person person) {
Log.e("skip", "call: " + person);
}
});
skipLast(int)忽略Observable发射的后n项数据。
Observable.from(list)
.skipLast(3)
.subscribe(new Action1<Person>() {
@Override
public void call(Person person) {
Log.e("skipLast", "call: " + person);
}
});
elementAt(int)用来获取元素Observable发射的事件序列中的第n项数据,并当做唯一的数据发射出去。
Observable.from(list)
.elementAt(3)
.subscribe(new Action1<Person>() {
@Override
public void call(Person person) {
Log.e("elementAt", "call: " + person);
}
});
first()顾名思义,它是的Observable只发送观测序列中的第一个数据项。
Observable.from(list)
.first()
.subscribe(new Action1<Person>() {
@Override
public void call(Person person) {
Log.e("first", "call: " + person);
}
});
last()只发射观测序列中的最后一个数据项。
Observable.from(list)
.last()
.subscribe(new Action1<Person>() {
@Override
public void call(Person person) {
Log.e("first", "call: " + person);
}
});
distinct去除重复,有无参形式:
Observable.just(2, 1, 2, 2, 3, 4, 3, 4, 5, 5)
.distinct()
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer i) {
System.out.print(i + " ");
}
});
还可以传入Func1对象,自己实现判断逻辑:
list.add(new Person(3, "js3"));
Observable.from(list)
.distinct(new Func1<Person, String>() {
@Override
public String call(Person p) {
return p.getName();
}
})
.subscribe(new Action1<Person>() {
@Override
public void call(Person person) {
Log.e("distinct", "call: " + person);
}
});
debounce操作符是对源Observable间隔期产生的结果进行过滤,如果在这个规定的间隔期内没有别的结果产生,则将这个结果提交给订阅者,否则忽略该结果,原理有点像光学防抖.
debounce(时间,时间单位)
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
if (subscriber.isUnsubscribed()) return;
try {
for (int i = 0; i < 10; i++) {
subscriber.onNext(i);
try {
Thread.currentThread().sleep(i * 1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
subscriber.onCompleted();
} catch (Exception e) {
subscriber.onError(e);
}
}
}).subscribeOn(Schedulers.newThread())
.debounce(5, TimeUnit.SECONDS)
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
LogUtils.d("------->call():" + integer);
}
});
最后输出结果是:
03-01 10:01:15.040 3591-3736/com.rxandroid.test1 D/----->: ------->call():5
03-01 10:01:20.030 3591-3736/com.rxandroid.test1 D/----->: ------->call():6
03-01 10:01:26.030 3591-3736/com.rxandroid.test1 D/----->: ------->call():7
03-01 10:01:33.030 3591-3736/com.rxandroid.test1 D/----->: ------->call():8
03-01 10:01:41.030 3591-3736/com.rxandroid.test1 D/----->: ------->call():9
ok,RxJava的过滤操作符就先介绍到这里,更多精彩内容,欢迎关注我的微信公众号——Android机动车