RxJava的map方法与flatMap方法

简单讲,map和flatMap都是来完成Observable构造的数据到Observer接收数据的一个转换,这么说有点绕😋,直接看Demo。

第一步,我们构造数据结构:

构造一个课程:

 1 package com.plbear.doncal.rxjavademo;
 2 
 3 public class Course {
 4     private String name;
 5 
 6     public Course(String name) {
 7         this.name = name;
 8     }
 9 
10     public String getName() {
11         return name;
12     }
13 
14     @Override
15     public String toString() {
16         return super.toString();
17     }
18 }

构造学生,一个学生可以选择多门课程:

 1 package com.plbear.doncal.rxjavademo;
 2 
 3 import java.util.ArrayList;
 4 import java.util.List;
 5 
 6 public class Student {
 7     private String name;
 8     private List<Course> courseList = new ArrayList<>();
 9 
10     public String getName() {
11         return name;
12     }
13 
14     public List<Course> getCourseList() {
15         return courseList;
16     }
17 
18     public void setCourseList(List<Course> courseList) {
19         this.courseList = courseList;
20     }
21 
22     public void setName(String name) {
23         this.name = name;
24     }
25 }

接下来初始化数据:

 1         List<Course> courses1 = new ArrayList<>();
 2 
 3         courses1.add(new Course("1"));
 4         courses1.add(new Course("2"));
 5         courses1.add(new Course("3"));
 6 
 7         Student student1 = new Student();
 8         student1.setName("student1");
 9         student1.setCourseList(courses1);
10 
11         List<Course> courses2 = new ArrayList<>();
12 
13         courses2.add(new Course("4"));
14         courses2.add(new Course("5"));
15         courses2.add(new Course("6"));
16 
17         Student student2 = new Student();
18         student2.setName("student2");
19         student2.setCourseList(courses2);
20         List<Student> students = new ArrayList<>();
21         students.add(student1);
22         students.add(student2);

第二步:如果不用map或者flatMap,打印所有学生的课程?

 1         rx.Observable.from(students)
 2                 .observeOn(AndroidSchedulers.mainThread())
 3                 .subscribe(new Subscriber<Student>() {
 4                     @Override
 5                     public void onCompleted() {
 6                         log("onCompleted");
 7                     }
 8 
 9                     @Override
10                     public void onError(Throwable e) {
11                         log("onError");
12                     }
13 
14                     @Override
15                     public void onNext(Student student) {
16                         for (int i = 0; i < student.getCourseList().size(); i++) {
17                             log("onNext:" + student.getCourseList().get(i).getName());
18                         }
19                     }
20                 });

输出如下:

1 10-16 18:12:21.266 19369 19369 E MainActivity: yanlog msg:onNext:1
2 10-16 18:12:21.266 19369 19369 E MainActivity: yanlog msg:onNext:2
3 10-16 18:12:21.266 19369 19369 E MainActivity: yanlog msg:onNext:3
4 10-16 18:12:21.266 19369 19369 E MainActivity: yanlog msg:onNext:4
5 10-16 18:12:21.267 19369 19369 E MainActivity: yanlog msg:onNext:5
6 10-16 18:12:21.267 19369 19369 E MainActivity: yanlog msg:onNext:6
7 10-16 18:12:21.267 19369 19369 E MainActivity: yanlog msg:onCompleted

如上面代码所示,我们使用Observable.from依次发射数据,发射的数据类型是student。但是我需要打印的是课程名啊,能否接收课程名呢?

第三步:使用map来转换

直接上代码:

 1         rx.Observable.from(students)
 2                 .map(new Func1<Student, List<Course>>() {
 3                     @Override
 4                     public List<Course> call(Student student) {
 5                         return student.getCourseList();
 6                     }
 7                 })
 8                 .observeOn(AndroidSchedulers.mainThread())
 9                 .subscribe(new Subscriber<List<Course>>() {
10                     @Override
11                     public void onCompleted() {
12                         log("onCompleted");
13                     }
14 
15                     @Override
16                     public void onError(Throwable e) {
17                         log("onError");
18                     }
19 
20                     @Override
21                     public void onNext(List<Course> courses) {
22                         for (int i = 0; i < courses.size(); i++) {
23                             log("onNext:" + courses.get(i).getName());
24                         }
25                     }
26                 });

如果你喜欢Lamba表达式的话,也可以这样:

 1         rx.Observable.from(students)
 2                 .map(student -> student.getCourseList())
 3                 .observeOn(AndroidSchedulers.mainThread())
 4                 .subscribe(new Subscriber<List<Course>>() {
 5                     @Override
 6                     public void onCompleted() {
 7                         log("onCompleted");
 8                     }
 9 
10                     @Override
11                     public void onError(Throwable e) {
12                         log("onError");
13                     }
14 
15                     @Override
16                     public void onNext(List<Course> courses) {
17                         for (int i = 0; i < courses.size(); i++) {
18                             log("onNext:" + courses.get(i).getName());
19                         }
20                     }
21                 });

看执行结果:

1 10-16 18:39:09.740 22392 22392 E MainActivity: yanlog msg:over
2 10-16 18:39:09.861 22392 22392 E MainActivity: yanlog msg:onNext:1
3 10-16 18:39:09.861 22392 22392 E MainActivity: yanlog msg:onNext:2
4 10-16 18:39:09.861 22392 22392 E MainActivity: yanlog msg:onNext:3
5 10-16 18:39:09.861 22392 22392 E MainActivity: yanlog msg:onNext:4
6 10-16 18:39:09.861 22392 22392 E MainActivity: yanlog msg:onNext:5
7 10-16 18:39:09.861 22392 22392 E MainActivity: yanlog msg:onNext:6
8 10-16 18:39:09.861 22392 22392 E MainActivity: yanlog msg:onCompleted

第四步:使用flatMap来转换

我们发现使用map之后,代码还是不够简单,里面有一个for循环结构,而RxJava实际上是要避免这种for循环结构的。那我们利用flatMap来看下:

 1         rx.Observable.from(students)
 2                 .flatMap(new Func1<Student, rx.Observable<Course>>() {
 3                     @Override
 4                     public rx.Observable<Course> call(Student student) {
 5                         return rx.Observable.from(student.getCourseList());
 6                     }
 7                 })
 8                 .observeOn(AndroidSchedulers.mainThread())
 9                 .subscribe(new Subscriber<Course>() {
10                     @Override
11                     public void onCompleted() {
12                         log("onCompleted");
13                     }
14 
15                     @Override
16                     public void onError(Throwable e) {
17                         log("onError");
18                     }
19 
20                     @Override
21                     public void onNext(Course courses) {
22                         log("onNext"+courses);
23                     }
24                 });

同样,我们给出lamba的实现:

 1         rx.Observable.from(students)
 2                 .flatMap(student -> rx.Observable.from(student.getCourseList()))
 3                 .observeOn(AndroidSchedulers.mainThread())
 4                 .subscribe(new Subscriber<Course>() {
 5                     @Override
 6                     public void onCompleted() {
 7                         log("onCompleted");
 8                     }
 9 
10                     @Override
11                     public void onError(Throwable e) {
12                         log("onError");
13                     }
14 
15                     @Override
16                     public void onNext(Course courses) {
17                         log("onNext"+courses);
18                     }
19                 });

看一下输出结果:

1 10-16 18:46:32.511 23190 23190 E MainActivity: yanlog msg:over
2 10-16 18:46:32.647 23190 23190 E MainActivity: yanlog msg:onNext1
3 10-16 18:46:32.647 23190 23190 E MainActivity: yanlog msg:onNext2
4 10-16 18:46:32.647 23190 23190 E MainActivity: yanlog msg:onNext3
5 10-16 18:46:32.648 23190 23190 E MainActivity: yanlog msg:onNext4
6 10-16 18:46:32.648 23190 23190 E MainActivity: yanlog msg:onNext5
7 10-16 18:46:32.648 23190 23190 E MainActivity: yanlog msg:onNext6
8 10-16 18:46:32.649 23190 23190 E MainActivity: yanlog msg:onCompleted

从上面可以看到,flatMap实际上是将一个Observable对象分拆成两个,然后再依次发送出去,从而达到可以去掉for循环,优化结构的目的。

 

posted @ 2018-10-16 18:50  程小白  阅读(5253)  评论(0编辑  收藏  举报