Rxjava系列二 转换操作符
前篇文章我们介绍了一下基本的概念,现在我们聊一聊RxJava中的操作符,Rxjava中的操作符主要分为三类
- 转换操作符(map flatMap concatMap FlatMapInterable SwitchMap Scan GroupBy)
- 过滤操作符(Fliter take takeLast takeUntil Distinc distincUntilChange Skip ...)
- 组合操作符(merge zip join combineLatest ...)
-
Map
map()函数接受一股额Func1类型的参数,然后把这个Func1应用到每一个由Observable发射的值上,将发射的值转化为我们期待的值。
举个例子: 假如我们的输入为一组数字,然后我们需要将每个数字都转化为字符串,至于转化为什么字符串随意。便可通过map来实现
Observable.just(1,2,3,4,5) .map(new Func1<Integer,String>(){ public String call(Integer i){ //1. 接受一个整数 并返回一个字符串 return "Hello" + i; } }).subscribe(new Action1<String>(){ public void call(Strings){ //2. 直接将字符串打印出来 System.out.println(s); } })
-
FlatMap
FlatMap函数同样也是做转换的,但是作用却不太一样,所以我打算举例说明,假设现在有这么一个需求,有一列学生类,学生类有一个名字和他所选的多个课程。如何打印出每个学生所选的所有课程的名字呢,首先我们想到的就是map中来遍历学生数组,然后在每个学生中遍历输出它的课程名称
Student[] students = ...; Subscriber<Student> subscriber = new Subscriber<Student>() { @Override public void onNext(Student student) { List<Course> courses = student.getCourses(); for (int i = 0; i < courses.size(); i++) { Course course = courses.get(i); } } ... }; Observable.from(students) .subscribe(subscriber);
这么做当然可以,但是现在我们使用了Rxjava 所以我们像将这个for循环去掉,这时候使用map显然无法满足我们的需求,因为map是一对一的转化,我们现在需要的是从每一个学生中选出多个课程,这显然是一个一对多的问题,这个是时候明显就是需要使用flatMap了。
Observable.from(students).flatMap(new Func1<Student, Observable<String>>() { @Override public Observable<String> call(Student student) { return Observable.from(student.getCourse()); } }).subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println("Courser " + s); } });
FlatMap与Map之间的区别:
- 都是将输入的参数转化之后返回明外一个对象
- flatMap返回的是一个Observable对象,并且这个Observable对象不是直接发送到Subscriber的回调方法中
FlatMap的原理:1. 使用传入的事件对象创建一个Observable对象 2. 并不发送这个Observable ,而是将它激活,于是它开始发送时间 3. 每一个创建的Observable发送的事件,都被汇入同一个Observable,而这个Observable负责将这些时间统一交给Subscriber的回调。在这个过程中并不能保证事件的顺序。
-
ConcatMap
ConcatMap解决了Flatmap的顺序问题,它能够把发射的值连续在一起。
-
Scan
scan()对一个序列的数据应用一个函数 两个参数,并将这个函数的结果发射出去作为下个数据应用合格函数时的第一个参数使用。
Observable.just(1, 2, 3, 4, 5) .scan(new Func2<Integer, Integer, Integer>() { @Override public Integer call(Integer integer, Integer integer2) { return integer + integer2; } }).subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { System.out.print(integer+“ ”); } });
输出结果为:1 3 6 10 15
-
GroupBy
groupBy()将原始Observable发射的数据按照key来拆分成一些小的Observable,然后这些小Observable分别发射其所包含的的数据。实际使用中,我们需要提供一个生成key的规则(也就是Func1中的call方法),所有key相同的数据会包含在同一个小的Observable中。
Observable<GroupedObservable<Integer, Student>> groupedObservableObservable = Observable.from(students).groupBy(s -> s.getScore()); Observable.concat(groupedObservableObservable).subscribe(s -> System.out.println(s));
通过生成一个groupedObservableObservable 一个带有GroupedObservable的序列, 基于一个分组的key,然后按照分组一次输出。