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

RxJava2.x 变换操作符之 flatMap & concatMap_第1张图片
题图:Pixabay License

哈喽,朋友们,上一篇文章我们学习了 filter 操作符,今天我们来学习 RxJava 中比较重要的两个操作符 flatMap 和 concatMap。

1.flatMap

我们知道 flat 是平的意思,这个翻译还是有点生硬和抽象,我们还是不太理解,你就可以先理解成平铺的意思吧。

flatMap 是变换操作符的一种,它将一个发射数据的 Observable 变换为多个 Observable,然后将他们发射的数据合并后放入一个单独的 Observable。

举个简单的例子吧,假设上游有个数据源,数据源是学生对象的集合,学生有姓名和课程的属性,每个学生的课程可以有多个,需求是打印出所有学生的课程名称。

        Student student1 = new Student();

        List 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 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 studentList = new ArrayList<>();
        studentList.add(student1);
        studentList.add(student2);

        Observable.just(studentList)
                .flatMap((Function, ObservableSource>) students -> Observable.fromIterable(students))
                .flatMap((Function>) student -> {
                    LogUtil.i(TAG, "student name===" + student.getName());
                    return Observable.fromIterable(student.getCourses());
                })
                .subscribe(course -> LogUtil.i(TAG, "course===" + course.getCourseName()));

执行结果如下:

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 操作符再看看打印的结果,修改代码如下:

    Observable.just(studentList)
                .concatMap((Function, ObservableSource>) students -> Observable.fromIterable(students))
                .concatMap((Function>) student -> {
                    LogUtil.i(TAG, "student name===" + student.getName());
                    return Observable.fromIterable(student.getCourses());
                })
                .subscribe(course -> LogUtil.i(TAG, "course===" + course.getCourseName()));

执行结果如下:

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

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

你可能感兴趣的:(Android,RxJava2.x,教程)