RxJava的map方法與flatMap方法
阿新 • • 發佈:2018-10-16
避免 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 privateString 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方法