前篇文章我們介紹了一下基本的概念妻熊,現(xiàn)在我們聊一聊RxJava中的操作符亚脆,Rxjava中的操作符主要分為三類
- 轉(zhuǎn)換操作符(map flatMap concatMap FlatMapInterable SwitchMap Scan GroupBy)
- 過濾操作符(Fliter take takeLast takeUntil Distinc distincUntilChange Skip ...)
- 組合操作符(merge zip join combineLatest ...)
-
Map
map()函數(shù)接受一股額Func1類型的參數(shù),然后把這個Func1應(yīng)用到每一個由Observable發(fā)射的值上,將發(fā)射的值轉(zhuǎn)化為我們期待的值。
舉個例子: 假如我們的輸入為一組數(shù)字,然后我們需要將每個數(shù)字都轉(zhuǎn)化為字符串望抽,至于轉(zhuǎn)化為什么字符串隨意。便可通過map來實現(xiàn)
Observable.just(1,2,3,4,5) .map(new Func1<Integer,String>(){ public String call(Integer i){ //1. 接受一個整數(shù) 并返回一個字符串 return "Hello" + i; } }).subscribe(new Action1<String>(){ public void call(Strings){ //2. 直接將字符串打印出來 System.out.println(s); } })
?
-
FlatMap
FlatMap函數(shù)同樣也是做轉(zhuǎn)換的履婉,但是作用卻不太一樣煤篙,所以我打算舉例說明,假設(shè)現(xiàn)在有這么一個需求毁腿,有一列學(xué)生類辑奈,學(xué)生類有一個名字和他所選的多個課程。如何打印出每個學(xué)生所選的所有課程的名字呢狸棍,首先我們想到的就是map中來遍歷學(xué)生數(shù)組身害,然后在每個學(xué)生中遍歷輸出它的課程名稱
Student[] students = ...; Subscriber<Student> subscriber = new Subscriber<Student>() { @Override public void onNext(Student student) { List<Course> courses = student.getCourses(); for (int i = 0; i < courses.size(); i++) { Course course = courses.get(i); } } ... }; Observable.from(students) .subscribe(subscriber);
這么做當(dāng)然可以味悄,但是現(xiàn)在我們使用了Rxjava 所以我們像將這個for循環(huán)去掉草戈,這時候使用map顯然無法滿足我們的需求,因為map是一對一的轉(zhuǎn)化侍瑟,我們現(xiàn)在需要的是從每一個學(xué)生中選出多個課程唐片,這顯然是一個一對多的問題丙猬,這個是時候明顯就是需要使用flatMap了。
Observable.from(students).flatMap(new Func1<Student, Observable<String>>() { @Override public Observable<String> call(Student student) { return Observable.from(student.getCourse()); } }).subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println("Courser " + s); } });
FlatMap與Map之間的區(qū)別:
- 都是將輸入的參數(shù)轉(zhuǎn)化之后返回明外一個對象
- flatMap返回的是一個Observable對象费韭,并且這個Observable對象不是直接發(fā)送到Subscriber的回調(diào)方法中
FlatMap的原理:1. 使用傳入的事件對象創(chuàng)建一個Observable對象 2. 并不發(fā)送這個Observable 茧球,而是將它激活,于是它開始發(fā)送時間 3. 每一個創(chuàng)建的Observable發(fā)送的事件星持,都被匯入同一個Observable抢埋,而這個Observable負責(zé)將這些時間統(tǒng)一交給Subscriber的回調(diào)。在這個過程中并不能保證事件的順序督暂。
-
ConcatMap
ConcatMap解決了Flatmap的順序問題揪垄,它能夠把發(fā)射的值連續(xù)在一起。
-
Scan
scan()對一個序列的數(shù)據(jù)應(yīng)用一個函數(shù) 兩個參數(shù)逻翁,并將這個函數(shù)的結(jié)果發(fā)射出去作為下個數(shù)據(jù)應(yīng)用合格函數(shù)時的第一個參數(shù)使用饥努。
Observable.just(1, 2, 3, 4, 5) .scan(new Func2<Integer, Integer, Integer>() { @Override public Integer call(Integer integer, Integer integer2) { return integer + integer2; } }).subscribe(new Action1<Integer>() { @Override public void call(Integer integer) { System.out.print(integer+“ ”); } });
輸出結(jié)果為:1 3 6 10 15
-
GroupBy
groupBy()將原始Observable發(fā)射的數(shù)據(jù)按照key來拆分成一些小的Observable,然后這些小Observable分別發(fā)射其所包含的的數(shù)據(jù)八回。實際使用中酷愧,我們需要提供一個生成key的規(guī)則(也就是Func1中的call方法),所有key相同的數(shù)據(jù)會包含在同一個小的Observable中缠诅。
Observable<GroupedObservable<Integer, Student>> groupedObservableObservable = Observable.from(students).groupBy(s -> s.getScore()); Observable.concat(groupedObservableObservable).subscribe(s -> System.out.println(s));
通過生成一個groupedObservableObservable 一個帶有GroupedObservable的序列溶浴, 基于一個分組的key,然后按照分組一次輸出。
?