1. 程式人生 > >RxJava的map方法與flatMap方法

RxJava的map方法與flatMap方法

避免 ide sch rri list activity 有一個 ade 接收

簡單講,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循環,優化結構的目的。

RxJava的map方法與flatMap方法