在 RxJava 1.x 理解-1 中,咱們說到了RxJava的簡單用法,可是這還遠遠不夠,由於html
輸入的數據 ---> 被監聽者(訂閱源)對這些數據進行操做,或者執行響應的處理 --> 產生新的數據,或者事件發送給監聽者 --> 監聽者執行本身的方法。java
其中,RxJava還能夠對輸入的數據進行變換,產生新數據(能夠是複雜的數據),而不是簡單的事件觸發。數組
/** * rxJava just 使用 * just --> 仍是使用的create方法 */ private void rxJavaJust() { Log.d(TAG, "----------- just ---------"); Observable .just("just 1", "just 2", "just 3") .subscribe(new Action1<String>() { @Override public void call(String s) { Log.d(TAG, "Item: " + s); } }); }
just會不斷的將可變參數數據 just 1 ;just 2 ;just 3 .... 發送出去ide
/** * rxJava from 使用 * from --> 仍是使用的create方法 */ private void rxJavaFrom() { Log.d(TAG, "----------- from ---------"); String[] names = {"1", "2", "3"}; Observable.from(names) .subscribe(new Subscriber<String>() { @Override public void onNext(String s) { Log.d(TAG, "Item: " + s); } @Override public void onCompleted() { Log.d(TAG, "Completed!"); } @Override public void onError(Throwable e) { Log.d(TAG, "Error!"); } }); Log.d(TAG, "----------- from2 ---------"); // 簡單來講就是數據提供了,並且是一個個的提供了,至於要如何執行,那就按觀察者本身的事情了。 Observable.from(names) .subscribe(new Action1<String>() { @Override public void call(String s) { Log.d(TAG, "Item: " + s); } }); }
from會不斷的將數組或者集合中的數據一個個發送出去post
/** * rxjava map 變換 * 將類型轉化成另外一個類型 */ private void rxJavaMap() { Log.d(TAG, "----------- Map ---------"); Observable.just("1") // 輸入類型 String .map(new Func1<String, Integer>() { @Override public Integer call(String s) { return Integer.parseInt(s); } }) .subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { Log.d(TAG, "Item: " + integer + " 執行調用 獲取線程id:" + Thread.currentThread().getId()); } }); }
Observable.just("999", "11") // 輸入類型 String .map(new Func1<String, List<Integer>>() { @Override public List<Integer> call(String s) { List<Integer> ints = new ArrayList<>(); ints.add(Integer.parseInt(s)); ints.add(Integer.parseInt(s)); ints.add(Integer.parseInt(s)); return ints; } }).subscribe(new Action1<List<Integer>>() { @Override public void call(List<Integer> integers) { int i = 0; // 這裏進行遍歷 for (Integer integer : integers) { Log.e(TAG, "Item " + i + " :" + +integer); i += 1; } } }); }
能夠看到,將String格式的數據轉換成了Integer格式的數據,或者是String格式的數據轉換成List<Integer>格式的數據。map是一對一的變換。測試
/** * rxjava flatMap 變換 * 事件再次分發: * * 從上面的代碼能夠看出, flatMap() 和 map() 有一個相同點:它也是把傳入的參數轉化以後返回另外一個對象。 * 但須要注意,和 map() 不一樣的是, flatMap() 中返回的是個 Observable 對象,但這個 Observable 對象並非被直接發送到了 Subscriber 的回調方法中。 * flatMap() 的原理是這樣的: * 1. 使用傳入的事件對象建立一個 Observable 對象; * 2. 並不發送這個 Observable, 而是將它激活,因而它開始發送事件; * 3. 每個建立出來的 Observable 發送的事件,都被匯入同一個 Observable ,而這個 Observable 負責將這些事件統一交給 Subscriber 的回調方法。 * 這三個步驟,把事件拆成了兩級,經過一組新建立的 Observable 將初始的對象『鋪平』以後經過統一路徑分發了下去。而這個『鋪平』就是 flatMap() 所謂的 flat。 */ private void rxJavaFlatMap() { Log.d(TAG, "----------- rxJavaFlatMap ---------"); List<Student> students = new ArrayList<>(); List<Source> sources = new ArrayList<>(); sources.add(new Source(1, "化學", 80)); sources.add(new Source(2, "物理", 79)); sources.add(new Source(3, "生物", 78)); students.add(new Student("小明1", 1, sources)); students.add(new Student("小明2", 1, sources)); Observable.from(students) .flatMap(new Func1<Student, Observable<Source>>() { @Override public Observable<Source> call(Student student) { Log.d(TAG, "Item: " + student.name); return Observable.from(student.mSources); } }) .subscribe(new Action1<Source>() { @Override public void call(Source source) { Log.d(TAG, "Item: " + source + " 執行調用 獲取線程id:" + Thread.currentThread().getId()); } }); }
// ------------------------ 測試使用的類 ----------------------------- class Student { String name;//學生名字 int id; List<Source> mSources;//每一個學生的全部課程 public Student(String name, int id, List<Source> sources) { this.name = name; this.id = id; mSources = sources; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", id=" + id + ", mSources=" + mSources + '}'; } } class Source { int sourceId;//id String name;//課程名 int score;//成績 public Source(int sourceId, String name, int score) { this.sourceId = sourceId; this.name = name; this.score = score; } @Override public String toString() { return "Source{" + "sourceId=" + sourceId + ", name='" + name + '\'' + ", score=" + score + '}'; } }
輸出結果:this
02-09 15:45:50.580 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: 小明1 02-09 15:45:50.581 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=1, name='化學', score=80} 執行調用 獲取線程id:2 02-09 15:45:50.581 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=2, name='物理', score=79} 執行調用 獲取線程id:2 02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=3, name='生物', score=78} 執行調用 獲取線程id:2 02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: 小明2 02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=1, name='化學', score=80} 執行調用 獲取線程id:2 02-09 15:45:50.582 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=2, name='物理', score=79} 執行調用 獲取線程id:2 02-09 15:45:50.583 3223-3223/pers.bolin.rxjavademo D/MainActivity: Item: Source{sourceId=3, name='生物', score=78} 執行調用 獲取線程id:2
其實上述代碼,也能夠用map實現:url
Observable.from(students).map(new Func1<Student, List<Source>>() { @Override public List<Source> call(Student student) { Log.d(TAG, "Item: " + student.name); return student.mSources; } }).subscribe(new Action1<List<Source>>() { @Override public void call(List<Source> sources) { // 主要的差距是這裏,咱們本身進行了一次循環遍歷。而flatMap則不用,直接獲取到的就是Source對象,而不是List<Source>對象 for (Source source:sources){ Log.d(TAG, "Item: " + source + " 執行調用 獲取線程id:" + Thread.currentThread().getId()); } } });
從上面的代碼能夠看出,
flatMap() 和 map() 有一個相同點:它也是把傳入的參數轉化以後返回另外一個對象。
但須要注意,和 map() 不一樣的是, flatMap() 中返回的是個 Observable 對象,但這個 Observable 對象並非被直接發送到了 Subscriber 的回調方法中。
flatMap() 的原理是這樣的:
1. 使用傳入的事件對象建立一個 Observable 對象;
2. 並不發送這個 Observable, 而是將它激活,因而它開始發送事件;
3. 每個建立出來的 Observable 發送的事件,都被匯入同一個 Observable ,而這個 Observable 負責將這些事件統一交給 Subscriber 的回調方法。
這三個步驟,把事件拆成了兩級,經過一組新建立的 Observable 將初始的對象『鋪平』以後經過統一路徑分發了下去。而這個『鋪平』就是 flatMap() 所謂的 flat。
總結:RxJava的做用就是
對於數據:對輸入的數據進行變換,轉換成想要的數據,而且能夠指定執行的線程,獲得最終的結果。
對於事件:觸發事件,觀察者感知,觀察者執行操做,而且能夠指定執行的線程。
參考資料:spa