
题图:Pixabay License
哈喽,朋友们,上一篇文章我们学习了 filter 操作符,今天我们来学习 RxJava 中比较重要的两个操作符 flatMap 和 concatMap。
1.flatMap
我们知道 flat 是平的意思,这个翻译还是有点生硬和抽象,我们还是不太理解,你就可以先理解成平铺的意思吧。
flatMap 是变换操作符的一种,它将一个发射数据的 Observable 变换为多个 Observable,然后将他们发射的数据合并后放入一个单独的 Observable。
举个简单的例子吧,假设上游有个数据源,数据源是学生对象的集合,学生有姓名和课程的属性,每个学生的课程可以有多个,需求是打印出所有学生的课程名称。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
| Student student1 = new Student();
List<Student.Course> list1 = new ArrayList<>(); list1.add(new Student.Course("语文1")); list1.add(new Student.Course("数学1")); list1.add(new Student.Course("英语1")); list1.add(new Student.Course("物理1")); list1.add(new Student.Course("化学1"));
student1.setName("张三"); student1.setCourses(list1);
Student student2 = new Student();
List<Student.Course> list2 = new ArrayList<>(); list2.add(new Student.Course("语文2")); list2.add(new Student.Course("数学2")); list2.add(new Student.Course("英语2"));
student2.setName("李四"); student2.setCourses(list2);
List<Student> studentList = new ArrayList<>(); studentList.add(student1); studentList.add(student2);
Observable.just(studentList) .flatMap((Function<List<Student>, ObservableSource<Student>>) students -> Observable.fromIterable(students)) .flatMap((Function<Student, ObservableSource<Student.Course>>) student -> { LogUtil.i(TAG, "student name===" + student.getName()); return Observable.fromIterable(student.getCourses()); }) .subscribe(course -> LogUtil.i(TAG, "course===" + course.getCourseName()));
|
执行结果如下:
1 2 3 4 5 6 7 8 9 10
| I/RxJavaOperatorActivity: student name===张三 I/RxJavaOperatorActivity: course===语文1 I/RxJavaOperatorActivity: course===数学1 I/RxJavaOperatorActivity: course===英语1 I/RxJavaOperatorActivity: course===物理1 I/RxJavaOperatorActivity: course===化学1 I/RxJavaOperatorActivity: student name===李四 I/RxJavaOperatorActivity: course===语文2 I/RxJavaOperatorActivity: course===数学2 I/RxJavaOperatorActivity: course===英语2
|
我们看到上面的代码没有 for 循环,却遍历打印了集合中的数据,RxJava 就是为了简化或者是取消 for 循环种方式,使用操作符来解决遍历循环的问题,从而是代码更加扁平化,使代码更加清晰和便于理解。
注意:flatMap 对这些 Observables 发射的数据做的是合并(merge)操作,因此它们可能是交错的,即不能保证数据的发射顺序。
2.concatMap
我们将上面的 flatMap 操作符换成 concatMap 操作符再看看打印的结果,修改代码如下:
1 2 3 4 5 6 7
| Observable.just(studentList) .concatMap((Function<List<Student>, ObservableSource<Student>>) students -> Observable.fromIterable(students)) .concatMap((Function<Student, ObservableSource<Student.Course>>) student -> { LogUtil.i(TAG, "student name===" + student.getName()); return Observable.fromIterable(student.getCourses()); }) .subscribe(course -> LogUtil.i(TAG, "course===" + course.getCourseName()));
|
执行结果如下:
1 2 3 4 5 6 7 8 9 10
| I/RxJavaOperatorActivity: student name===张三 I/RxJavaOperatorActivity: course===语文1 I/RxJavaOperatorActivity: course===数学1 I/RxJavaOperatorActivity: course===英语1 I/RxJavaOperatorActivity: course===物理1 I/RxJavaOperatorActivity: course===化学1 I/RxJavaOperatorActivity: student name===李四 I/RxJavaOperatorActivity: course===语文2 I/RxJavaOperatorActivity: course===数学2 I/RxJavaOperatorActivity: course===英语2
|
我们看到和 flatMap 的执行结果是一样的,我们发现打印的结果也是按照添加数据的顺序打印出来了,理论上 flatMap 执行的结果可能会有交错,原因是我们添加的数据过少,因此它们执行的时间也是差不多的,所以提现不出交错的情况。
好了,今天的学习内容就算完成了,感觉是不是非常简单?其实有时候你光看,理解起来是很慢的,但是你动手敲一遍立马就明白了,所以代码这个东西还是得多敲!
最后,我这边建了一个技术交流群,需要的朋友可以扫描下面的二维码加我微信并备注「加群」,拉你进入技术交流群!

飞哥带你去装逼,一直装逼到天黑!
另外,我还建了一个免费的知识星球用于学习交流,感兴趣的可以使用微信扫码加入哦!
