前言
按照官方的分類,操作符大致分為以下幾種:
- Creating Observables(Observable的創建操作符),比如:Observable.create()、Observable.just()、Observable.from()等等;
- Transforming Observables(Observable的轉換操作符),比如:observable.map()、observable.flatMap()、observable.buffer()等等;
- Filtering Observables(Observable的過濾操作符),比如:observable.filter()、observable.sample()、observable.take()等等;
- Combining Observables(Observable的組合操作符),比如:observable.join()、observable.merge()、observable.combineLatest()等等;
- Error Handling Operators(Observable的錯誤處理操作符),比如:observable.onErrorResumeNext()、observable.retry()等等;
- Observable Utility Operators(Observable的功能性操作符),比如:observable.subscribeOn()、observable.observeOn()、observable.delay()等等;
- Conditional and Boolean Operators(Observable的條件操作符),比如:observable.amb()、observable.contains()、observable.skipUntil()等等;
- Mathematical and Aggregate Operators(Observable數學運算及聚合操作符),比如:observable.count()、observable.reduce()、observable.concat()等等;
- 其他如observable.toList()、observable.connect()、observable.publish()等等;
1、創建型操作符
-
create操作符
create操作符是所有創建型操作符的“根”,也就是說其他創建型操作符最后都是通過create操作符來創建Observable的
-
from操作符
from操作符是把其他類型的對象和數據類型轉化成Observable
-
just操作符
just操作符也是把其他類型的對象和數據類型轉化成Observable,它和from操作符很像,只是方法的參數有所差別
-
defer操作符
defer操作符是直到有訂閱者訂閱時,才通過Observable的工廠方法創建Observable并執行
-
timer操作符
timer操作符是創建一串連續的數字,產生這些數字的時間間隔是一定的
-
interval操作符
interval操作符是每隔一段時間就產生一個數字,這些數字從0開始,一次遞增1直至無窮大;interval操作符的實現效果跟上面的timer操作符的第二種情形一樣
-
range操作符
range操作符是創建一組在從n開始,個數為m的連續數字,比如range(3,10),就是創建3、4、5…12的一組數字
-
repeat/repeatWhen操作符
repeat操作符是對某一個Observable,重復產生多次結果
repeatWhen操作符是對某一個Observable,有條件地重新訂閱從而產生多次結果
2、Observable的轉換操作符
-
buffer
buffer操作符周期性地收集源Observable產生的結果到列表中,并把這個列表提交給訂閱者,訂閱者處理后,清空buffer列表,同時接收下一次收集的結果并提交給訂閱者,周而復始
-
flatmap
把Observable產生的結果轉換成多個Observable,然后把這多個Observable“扁平化”成一個Observable,并依次提交產生的結果給訂閱者
-
concatMap操作符
flatMap操作符不同的是,concatMap操作符在處理產生的Observable時,采用的是“連接(concat)”的方式,而不是“合并(merge)”的方式,這就能保證產生結果的順序性,也就是說提交給訂閱者的結果是按照順序提交的,不會存在交叉的情況
-
switchMap
與flatMap操作符不同的是,switchMap操作符會保存最新的Observable產生的結果而舍棄舊的結果
-
groupBy操作符
groupBy操作符是對源Observable產生的結果進行分組,形成一個類型為GroupedObservable的結果集,GroupedObservable中存在一個方法為getKey(),可以通過該方法獲取結果集的Key值
-
cast操作符
而cast操作符主要是做類型轉換的
-
scan操作符
scan操作符通過遍歷源Observable產生的結果,依次對每一個結果項按照指定規則進行運算,計算后的結果作為下一個迭代項參數,每一次迭代項都會把計算結果輸出給訂閱者
-
window操作符
window操作符非常類似于buffer操作符,區別在于buffer操作符產生的結果是一個List緩存,而window操作符產生的結果是一個Observable,訂閱者可以對這個結果Observable重新進行訂閱處理
3、Observable的過濾操作符
-
debounce操作符
debounce操作符對源Observable每產生一個結果后,如果在規定的間隔時間內沒有別的結果產生,則把這個結果提交給訂閱者處理,否則忽略該結果。
-
distinct操作符
distinct操作符對源Observable產生的結果進行過濾,把重復的結果過濾掉,只輸出不重復的結果給訂閱者,非常類似于SQL里的distinct關鍵字。
-
elementAt操作符
elementAt操作符在源Observable產生的結果中,僅僅把指定索引的結果提交給訂閱者,索引是從0開始的
-
filter操作符
filter操作符是對源Observable產生的結果按照指定條件進行過濾,只有滿足條件的結果才會提交給訂閱者
-
ofType操作符
ofType操作符類似于filter操作符,區別在于ofType操作符是按照類型對結果進行過濾
-
first操作符
first操作符是把源Observable產生的結果的第一個提交給訂閱者,first操作符可以使用elementAt(0)和take(1)替代
-
single操作符
single操作符是對源Observable的結果進行判斷,如果產生的結果滿足指定條件的數量不為1,則拋出異常,否則把滿足條件的結果提交給訂閱者
-
last操作符
last操作符把源Observable產生的結果的最后一個提交給訂閱者,last操作符可以使用takeLast(1)替代
-
ignoreElements操作符
ignoreElements操作符忽略所有源Observable產生的結果,只把Observable的onCompleted和onError事件通知給訂閱者。ignoreElements操作符適用于不太關心Observable產生的結果,只是在Observable結束時(onCompleted)或者出現錯誤時能夠收到通知
-
skip操作符
skip操作符針對源Observable產生的結果,跳過前面n個不進行處理,而把后面的結果提交給訂閱者處理
-
skipLast操作符
skipLast操作符針對源Observable產生的結果,忽略Observable最后產生的n個結果,而把前面產生的結果提交給訂閱者處理,
-
take操作符
take操作符是把源Observable產生的結果,提取前面的n個提交給訂閱者,而忽略后面的結果
-
takeFirst操作符
takeFirst操作符類似于take操作符,同時也類似于first操作符,都是獲取源Observable產生的結果列表中符合指定條件的前一個或多個,與first操作符不同的是,first操作符如果獲取不到數據,則會拋出NoSuchElementException異常,而takeFirst則會返回一個空的Observable,該Observable只有onCompleted通知而沒有onNext通知。
-
takeLast操作符
takeLast操作符是把源Observable產生的結果的后n項提交給訂閱者
4、Observable的組合操作符
-
combineLatest操作符
combineLatest操作符把兩個Observable產生的結果進行合并,合并的結果組成一個新的Observable。這兩個Observable中任意一個Observable產生的結果,都和另一個Observable最后產生的結果,按照一定的規則進行合并
-
join操作符
join操作符把類似于combineLatest操作符,也是兩個Observable產生的結果進行合并,合并的結果組成一個新的Observable,但是join操作符可以控制每個Observable產生結果的生命周期
-
groupJoin操作符
groupJoin操作符非常類似于join操作符,區別在于join操作符中第四個參數的傳入函數不一致
-
merge操作符
merge操作符是按照兩個Observable提交結果的時間順序,對Observable進行合并
-
mergeDelayError操作符
從merge操作符的流程圖可以看出,一旦合并的某一個Observable中出現錯誤,就會馬上停止合并,并對訂閱者回調執行onError方法,而mergeDelayError操作符會把錯誤放到所有結果都合并完成之后才執行
-
startWith操作符
startWith操作符是在源Observable提交結果之前,插入指定的某些數據
-
switchOnNext操作符
switchOnNext操作符是把一組Observable轉換成一個Observable,轉換規則為:對于這組Observable中的每一個Observable所產生的結果,如果在同一個時間內存在兩個或多個Observable提交的結果,只取最后一個Observable提交的結果給訂閱者
-
zip操作符
zip操作符是把兩個observable提交的結果,嚴格按照順序進行合并,其流程圖如下:
5、 Observable的錯誤處理操作符
-
onErrorReturn操作符
onErrorReturn操作符是在Observable發生錯誤或異常的時候(即將回調oError方法時),攔截錯誤并執行指定的邏輯,返回一個跟源Observable相同類型的結果,最后回調訂閱者的onComplete方法
-
onErrorResumeNext操作符
onErrorResumeNext操作符跟onErrorReturn類似,只不過onErrorReturn只能在錯誤或異常發生時只返回一個和源Observable相同類型的結果,而onErrorResumeNext操作符是在錯誤或異常發生時返回一個Observable,也就是說可以返回多個和源Observable相同類型的結果
-
onExceptionResumeNext操作符
onExceptionResumeNext操作符和onErrorResumeNext操作符類似,不同的地方在于onErrorResumeNext操作符是當Observable發生錯誤或異常時觸發,而onExceptionResumeNext是當Observable發生異常時才觸發
-
retry操作符
retry操作符是當Observable發生錯誤或者異常時,重新嘗試執行Observable的邏輯,如果經過n次重新嘗試執行后仍然出現錯誤或者異常,則最后回調執行onError方法;當然如果源Observable沒有錯誤或者異常出現,則按照正常流程執行
常用操作符(舉例學習)
(1)Observable.from()。
使用from( )創建Observable,遍歷集合,發送每個item:
List list = new ArrayList<>();
list.add("from1");
list.add("from2");
list.add("from3");
Observable fromObservable = Observable.from(list); //遍歷list 每次發送一個
關于創建的操作符,我在前邊的文章里已經總結過,這里不再列舉。有興趣 的同學可以參考本系列第一篇文章 RxJava入門與提高(1)
(2)Observable.map()
用來把一個事件轉換為另一個事件。
map()操作符就是用于變換Observable對象的,map操作符返回一個Observable對象,這樣就可以實現鏈式調用,在一個Observable對象上多次使用map操作符,最終將最簡潔的數據傳遞給Subscriber對象。
特性:
它不必返回Observable對象返回的類型,你可以使用map操作符返回一個發出新的數據類型的observable對象。
可以對一個Observable多次使用map
用一個例子來練習:
//剛創建的Observable是String類型的
Observable.just("Hellp Map Operator")
.map(new Func1<String, Integer>() {
@Override
public Integer call(String s) {
return 2015;//通過第一個map轉成Integer
}
}).map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
return String.valueOf(integer);//再通過第二個map轉成String
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
System.out.println(s);
}
});
Run起來輸出日志: 2015
(3)Observable.flatMap()
Observable.flatMap()接收一個Observable的輸出作為參數輸入,同時輸出另外一個Observable。這一點很類似于map()。稍后總結flatMap()與map()。
舉例說明
List<String> list = Arrays.asList("Java", "Android", "Ruby", "Ios", "Swift");
//注意這里的Func1的參數List<String>是 .just(list)返回的Observable的輸出,并且返會一個Observable<String>
Observable.just(list)
.flatMap(new Func1<List<String>, Observable<String>>() {
@Override
public Observable<String> call(List<String> strings) {
//結合from處理
return Observable.from(strings);
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
System.out.println("_flatMap:"+s);
}
});
日志:
_flatMap:Java
_flatMap:Android
_flatMap:Ruby
_flatMap:Ios
_flatMap:Swift
假設這時候我們需要處理一下所獲取的結果,我們加個前綴,在保證不修改subscriber的前提下我們可以這么做:
增加個函數,用來增加個前綴:
static Observable<String>addPre(String lan){
return Observable.just("addPre_"+lan);
}
Observable.just(list)
.flatMap(new Func1<List<String>, Observable<String>>() {
@Override
public Observable<String> call(List<String> strings) {
return Observable.from(strings);
}
}).flatMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String s) {
//我們在這里調用`addPre`方法,就行處理
return addPre(s);
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
System.out.println(s);
}
});
輸出日志
addPre_Java
addPre_Android
addPre_Ruby
addPre_Ios
addPre_Swift
- 小結 :flatMap()與map()
(1)flatMap()與map()變換操作完后,都是返回的Observable對象,即數據源,這樣可以繼續發射數據,或者調用subscribe去叫接收員接收數據。
(2)map()中的Func類重寫的的call()方法的入參是 轉換前的Observable對象 發射的數據內容(可以理解為Observable對象里邊包含的數據內容),返回的數據是轉換后的Observable對象要發射的數據。
flatMap()中的Func類重寫的的call()方法的入參也是 轉換前的Observable對象 發射的數據內容,返回的數據是Observable對象。
代碼片段
.map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
return String.valueOf(integer);//再通過第二個map轉成String,返回String
}
})
*******************************************************
.flatMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String s) {
//我們在這里調用`addPre`方法,返回的是Observable<String>
return addPre(s);
}
}
(3)flatMap()處理集合、數組等,map()處理單一對象數據。
(4)Buffer
Buffer操作符定期收集Observable的數據放進一個數據包裹,然后發射這些數據包裹,而不是一次發射一個值。
Buffer操作符將一個Observable變換為另一個,原來的Observable正常發射數據,變換產生的Observable發射這些數據的緩存集合。
RxView.clickEvents(mButton)
.buffer(2, TimeUnit.SECONDS)
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Subscriber<List<ViewClickEvent>>() {
@Override
public void onCompleted() {}
@Override
public void onError(Throwable e) {}
@Override
public void onNext(List<ViewClickEvent> viewClickEvents) {
if (viewClickEvents.size() > 0) {
Toast.makeText(MainActivity.this, "2秒內點擊了" + viewClickEvents.size() + "次", Toast.LENGTH_SHORT).show();
} else {
}
}
});
如果原來的Observable發射了一個onError通知,Buffer會立即傳遞這個通知,而不是首先發射緩存的數據,即使在這之前緩存中包含了原始Observable發射的數據。
- 再舉個栗子
將原發射出來的數據已count為單元打包之后在分別發射出來
Observable.just(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
.buffer(3)
.subscribe(new Action1<Object>() {
@Override
public void call(Object o) {
System.out.println("onNext--> " + o);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
System.out.println("onError--> " + throwable.getMessage());
}
}, new Action0() {
@Override
public void call() {
System.out.println("onComplete");
}
});
日志:
onNext--> [1, 2, 3]
onNext--> [4, 5, 6]
onNext--> [7, 8, 9]
onNext--> [10]
onComplete
GroupBy
GroupBy操作符將原始Observable發射的數據按照key來拆分成一些小的Observable,然后這些小的Observable分別發射其所包含的的數據。
Observable.just(1, 2, 3, 4, 5, 6)
.groupBy(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer % 2 == 0;
}
})
.subscribe(new Action1<GroupedObservable<Boolean, Integer>>() {
@Override
public void call(final GroupedObservable<Boolean, Integer> observable) {
//toList方法轉換為Observable<List<T>>
observable.toList().subscribe(new Action1<List<Integer>>() {
@Override
public void call(List<Integer> integers) {
Log.d(TAG, "key=" + observable.getKey() + ",values=" + integers);
//key=false,values=[1, 3, 5]
//key=true,values=[2, 4, 6]
}
});
}
});
Filter
Filter返回滿足過濾條件的數據。
Observable.from(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9})
.filter(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer < 5;
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.d(TAG, "integer=" + integer); //1,2,3,4
}
});
First
First操作符返回第一條數據或者返回滿足條件的第一條數據。
Observable.from(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9})
.first()
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.d(TAG, "integer=" + integer); //1 返回第一條數據
}
});
Observable.from(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9})
.first(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer > 3;
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.d(TAG, "integer=" + integer); //4 返回滿足條件的第一條數據
}
});
Last
Last操作符返回最后一條數據或者滿足條件的最后一條數據。
Skip
Skip操作符將源Observable發射的數據過濾掉前n項。
Observable.from(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9})
.skip(6)
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.d(TAG, "integer=" + integer); //7,8,9
}
});
Take
Take操作符只取前n項。
Observable.from(new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9})
.take(2)
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.d(TAG, "integer=" + integer); //1,2
}
});
- 說明:根據我的學習和研究,個人覺得filter、first、等操作符與map的用法類似,感覺都可以用map()自己封裝。
本文暫時總結這些,如果以后有總結,在更新。
關于線程控制,放在下篇講解。
歡迎繼續收看:RxJava入門與提高-線程控制Scheduler篇(4)
作者:ZhangYushui
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。