RxJava2.x 变换操作符之 flatMap 和 concatMap


题图: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 执行的结果可能会有交错,原因是我们添加的数据过少,因此它们执行的时间也是差不多的,所以提现不出交错的情况。

好了,今天的学习内容就算完成了,感觉是不是非常简单?其实有时候你光看,理解起来是很慢的,但是你动手敲一遍立马就明白了,所以代码这个东西还是得多敲!

最后,我这边建了一个技术交流群,需要的朋友可以扫描下面的二维码加我微信并备注「加群」,拉你进入技术交流群!

飞哥带你去装逼,一直装逼到天黑!

另外,我还建了一个免费的知识星球用于学习交流,感兴趣的可以使用微信扫码加入哦!

在这里插入图片描述

本文标题:RxJava2.x 变换操作符之 flatMap 和 concatMap

文章作者:x-sir

发布时间:2019年05月27日 - 23:17

最后更新:2019年05月27日 - 23:17

原始链接:http://www.x-sir.com/2019/05/27/RxJava2.x 变换操作符之 flatMap和concatMap/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

-------------本文结束感谢您的阅读-------------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%