1.前言
在前一篇文章中向大家介绍了转换操作符,如果对转换操作符不是很清楚的建议可以去看一下RxJava—转换操作符。那么在这一章中我们就来介绍RxJava中的过滤操作符,顾名思义过滤操作符主要就是对事件数据根据相应的条件进行过滤,只返回满足过滤条件的数据,过滤操作符主要包括:Filter()、Take()、TakeLast()、TakeUntil()、Skip()、SkipLast()、ElementAt()、Debounce()、 DistinctUntilChange()、First()、Last()等。
2.过滤操作符的使用
(1)Filter
filter(Func1)用来过滤被观察者中我们不想要的数据,只返回满足条件的值。
根据官方给出的原理图:
还是用上一篇文章的数据来进行演示,这个时候我需要得到班级里所有男生的学号和姓名,我们可以这样实现:
Observable.from(studentList)
.filter(new Func1<Student, Boolean>()
{
public Boolean call(Student student)
{
return "男".equals(student.getGender());
}
})
.subscribe(new Action1<Student>()
{
public void call(Student student)
{
Log.d("filter", "学号:" + student.getNumber()
+ " 姓名:" + student.getName());
}
});
从上面的代码中可以看出Func1的两个参数分别表示的是Observable的发射值的类型和是否返回Observable的发射值,当为true时就是要返回发射值,当为false时就是过滤数据,不返回发射值。当点击按钮后在控制台上,可以看到这样的结果:
(2)Take
take(int)用一个整数n作为一个参数,从原始的序列中发射前n个元素。
根据官方给出的原理图:
Observable.from(studentList)
.take(5)
.subscribe(new Action1<Student>()
{
public void call(Student student)
{
Log.d("Take", "学号:" + student.getNumber()
+ " 姓名:" + student.getName());
}
});
从上面的代码中可以看出take()中的参数是多少就代表发射数据源的前多少项数据
。
当点击按钮后在控制台上,可以看到这样的结果:
根据官方给出的原理图:
Observable.from(studentList)
.takeLast(3)
.subscribe(new Action1<Student>()
{
public void call(Student student)
{
Log.d("takeLast", "学号:" + student.getNumber()
+ " 姓名:" + student.getName());
}
});
从上面的代码中可以看出takeLast()中的参数是多少就代表发射数据源的后多少项数据
。
当点击按钮后在控制台上,可以看到这样的结果:
根据官方给出的原理图:
Observable<Long> observableA = Observable.interval(300, TimeUnit.MILLISECONDS);
Observable<Long> observableB = Observable.interval(800, TimeUnit.MILLISECONDS);
observableA.takeUntil(observableB)
.subscribe(new Subscriber<Long>()
{
public void onCompleted()
{
Log.d("takeUntil", "完成");
}
public void onError(Throwable e)
{
Log.d("takeUntil", "错误");
}
public void onNext(Long aLong)
{
Log.d("takeUntil", " " + aLong);
}
});
根据官方给出的原理图:
Observable.from(studentList)
.takeUntil(new Func1<Student, Boolean>()
{
public Boolean call(Student student)
{
if("A007".equals(student.getNumber()))
{
return true;
}
else
{
return false;
}
}
})
.subscribe(new Action1<Student>()
{
public void call(Student student)
{
Log.d("takeUntil", "学号:" + student.getNumber()
+ " 姓名:" + student.getName());
}
});
从上面的代码中可以看出,打印出了所有学号在A007之前的所有学生,但是要注意的是这里的takeUntil()操作符可不是打印出前7个学生的信息,而是从头顺序的打印出来,直到打印出学号为A007的学生信息后停止。
当点击按钮后在控制台上,可以看到这样的结果:
根据官方给出的原理图:
根据官方给出的原理图:
(7)ElementAt
elementAt(int)用来获取元素Observable发射的事件序列中的第n项数据,并当做唯一的数据发射出去。
根据官方给出的原理图:
根据官方给出的原理图:
根据官方给出的原理图:
根据官方给出的原理图:
Observable.just(1, 1, 3, 3, 5, 7, 7, 7, 9, 9)
.distinct()
.subscribe(new Action1<Integer>()
{
public void call(Integer integer)
{
Log.d("distinct", String.valueOf(integer));
}
});
程序输出为:1,3,5,7,9
根据官方给出的原理图:
现在我们需要得到班级里第一个男同学和第一个女同学的学号和姓名,我们可以这样实现:
Observable.from(studentList)
.distinct(new Func1<Student, String>()
{
public String call(Student student)
{
return student.getGender();
}
})
.subscribe(new Action1<Student>()
{
public void call(Student student)
{
Log.d("distinct", "学号:" + student.getNumber()
+ " 姓名:" + student.getName());
}
});
从上面的代码中可以看出在distinct(Func1)方法中,是通过call()方法返回的值来判断数据是否相同。当点击按钮后在控制台上,可以看到这样的结果:
(10)DistinctUntilChanged
distinctUntilChanged()和distinct()类似,只不过它判定的是Observable发射的当前数据项和前一个数据项是否相同。
根据官方给出的原理图:
同样还是上面过滤数字的例子:
Observable.just(1, 1, 3, 3, 5, 7, 7, 7, 9, 9)
.distinctUntilChanged()
.subscribe(new Action1<Integer>()
{
public void call(Integer integer)
{
Log.d("distinctUntilChanged", String.valueOf(integer));
}
});
程序输出为:1,3,5,7,9
distinctUntilChanged(Func1)和distinct(Func1)一样,根据Func1中call方法产生一个Key来判断两个相邻的数据项是否相同。
根据官方给出的原理图:
(11)First
first()顾名思义,它是的Observable只发送观测序列中的第一个数据项。
根据官方给出的原理图:
现在我们要获取班级中第一个学生的学号和姓名,我们可以这样实现:
Observable.from(studentList)
.first()
.subscribe(new Action1<Student>()
{
public void call(Student student)
{
Log.d("first", "学号:" + student.getNumber()
+ " 姓名:" + student.getName());
}
});
first(Func1)只发送符合条件的第一个数据项。
根据官方给出的原理图:
现在我们要获取班级中学号为A007的学生的学号和姓名,我们可以这样实现:
Observable.from(studentList)
.first(new Func1<Student, Boolean>()
{
public Boolean call(Student student)
{
return "007".equals(student.getNumber());
}
})
.subscribe(new Action1<Student>()
{
public void call(Student student)
{
Log.d("first", "学号:" + student.getNumber()
+ " 姓名:" + student.getName());
}
});
从上面的代码可以看出,first(Func1)方法中是通过call()方法的返回值来判断是否发射Observable中的数据,当返回值为true时发射数据,当返回值为false时不发射数据。
(12)Last
last()只发射观测序列中的最后一个数据项,和first()的用法相同,这里就不做过多的介绍。
根据官方给出的原理图:
根据官方给出的原理图:
3.总结