RxJava和java8的Stream類似 都是對資料流進行操作
基於rxJava版本rxjava2-2.0.1
Rxjava常用操作符
建立
create
通過建立回撥函式自定義subscribe傳送
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onNext(1);
subscriber.onNext(2);
subscriber.onNext(3);
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print(integer + ",");
}
});
//結果
1,2,3,
複製程式碼
just
將單個item作為輸入,然後單項傳送給subscribe
Observable.just(1, 2, 3).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print(integer + ",");
}
});
//結果
1,2,3,
複製程式碼
from
將陣列作為輸入,然後依次單個傳送給subscribe
Observable.from(Arrays.asList(1, 2, 3)).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print(integer + ",");
}
});
//結果
1,2,3,
複製程式碼
Empty/Never/Throw
Empty:建立一個不發射任何資料但是正常終止的Observable(呼叫complete) Never:建立一個不發射資料也不終止的Observable(不呼叫complete) Throw:建立一個不發射資料以一個錯誤終止的Observable(呼叫error)
System.out.println("\nEmpty:");
Observable.empty().subscribe(new Subscriber<Object>() {
@Override
public void onCompleted() {
System.out.print("onCompleted");
}
@Override
public void onError(Throwable e) {
System.out.print("onError");
}
@Override
public void onNext(Object o) {
System.out.print("onNext");
}
});
System.out.println("\nNever:");
Observable.never().subscribe(new Subscriber<Object>() {
@Override
public void onCompleted() {
System.out.print("onCompleted");
}
@Override
public void onError(Throwable e) {
System.out.print("onError");
}
@Override
public void onNext(Object o) {
System.out.print("onNext");
}
});
//結果
Empty:
onCompleted
Never:
複製程式碼
Interval
建立一個按固定時間間隔發射整數序列的Observable(非同步的) Timer效果與其類似,不建議使用
Observable.interval(1, TimeUnit.MILLISECONDS).subscribe(new Subscriber<Object>() {
@Override
public void onCompleted() {
System.out.print("onCompleted");
}
@Override
public void onError(Throwable e) {
System.out.print("onError");
}
@Override
public void onNext(Object o) {
System.out.print("onNext");
}
});
//結果 每隔一秒生成一個next
複製程式碼
Range
Range操作符發射一個範圍內的有序整數序列,你可以指定範圍的起始和長度。
Observable.range(7, 3).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print(integer + ",");
}
});
//結果
7,8,9,
複製程式碼
repeat
重複資料傳送n遍 repeatWhen指定條件才重複傳送
Observable.just(1, 2)
.repeat(2)
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print(integer + " ");
}
});
//結果
1 2 1 2
複製程式碼
轉換
Buffer
定期收集Observable的資料放進一個資料包裹,然後發射這些資料集合。(感覺應用場景:將陣列按照拆分成大小相同的多個子陣列)
Observable.range(2, 6).buffer(3)
.subscribe(new Subscriber<List<Integer>>() {
@Override
public void onCompleted() {
System.out.printf("onCompleted\n");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(List<Integer> integers) {
System.out.printf(integers.toString());
}
});
//結果
[2, 3, 4][5, 6, 7]onCompleted
複製程式碼
window
定期將來自原始Observable的資料分解為一個Observable視窗,發射這些視窗,而不是每次發射一項資料
Observable.range(2, 6).window(3)
.subscribe(new Subscriber<Observable<Integer>>() {
@Override
public void onCompleted() {
System.out.printf("w-Completed\n");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Observable<Integer> integerObservable) {
integerObservable.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
System.out.printf("inner-Completed\n");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Integer integer) {
System.out.printf(integer + ",");
}
});
}
});
//結果
2,3,4,inner-Completed
5,6,7,inner-Completed
w-Completed
複製程式碼
cast
在Observable發射資料前將所有資料型別進行強轉為指定型別
Observable.just(2.5F, 3, 5F, 0.6F).cast(Object.class).subscribe(new Action1<Object>() {
@Override
public void call(Object s) {
System.out.print(s + ",");
}
});
//結果
2.5,3,5.0,0.6,
複製程式碼
Map
僅僅是將資料進行轉換
Observable.range(2, 5).map(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
return integer + "call";
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
System.out.printf(s + ",");
}
});
//結果
2call,3call,4call,5call,6call,
複製程式碼
FlatMap
將Observable發射的資料變換為Observables集合,然後將這些Observable發射的資料平坦化的放進一個單獨的Observable,內部採用merge合併。(就是將資料轉化為Observable,實際應用場景:將陣列資料項通過from轉成Observable,然後通過Merge將Observables中的資料項都平展開到新的Observable中,成為了將多維陣列降維的目的)
Observable.create(new Observable.OnSubscribe<List<Integer>>() {
@Override
public void call(Subscriber<? super List<Integer>> subscriber) {
subscriber.onNext(Arrays.asList(1, 2, 3, 4, 5));
}
}).flatMap(new Func1<List<Integer>, Observable<Integer>>() {
@Override
public Observable<Integer> call(List<Integer> integers) {
return Observable.from(integers);
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.printf(integer + ",");
}
});
//結果
1,2,3,4,5,
複製程式碼
GroupBy
將Observable分拆為Observable集合,將原始Observable發射的資料按Key分組,每一個Observable發射一組不同的資料。(其實就是將資料項對應生成Key處理後轉為一個Observable)
Observable.range(0, 10).groupBy(new Func1<Integer, Integer>() {
@Override
public Integer call(Integer integer) {
return integer % 3;
}
}).subscribe(new Action1<GroupedObservable<Integer, Integer>>() {
@Override
public void call(final GroupedObservable<Integer, Integer> item) {
item.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
System.out.print(item.getKey() + ":" + "onCompleted");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Integer integer) {
System.out.printf(item.getKey() + ":" + integer + ",");
}
});
}
});
//結果
0:0,1:1,2:2,0:3,1:4,2:5,0:6,1:7,2:8,0:9,0:onCompleted1:onCompleted2:onCompleted
複製程式碼
Scan
對Observable發射的每一項資料應用一個函式,然後按順序依次發射每一個值。
Observable.range(0, 5).scan(new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer sum, Integer item) {
return sum + item;
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.printf(integer + ",");
}
});
//結果
0,1,3,6,10,
複製程式碼
過濾
Debounce
過濾特定時間內最近的資料傳送,其他資料不傳送。
Observable.just(1, 2, 3)
.debounce(400, TimeUnit.MILLISECONDS)
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print("integer=" + integer);
}
});
//結果:過濾400毫秒後最近的一個
integer=3
複製程式碼
Sample
週期性傳送最近的資料
Observable.interval(300, TimeUnit.MILLISECONDS)
.sample(500, TimeUnit.MILLISECONDS)
.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
System.out.print("s=" + aLong + ",");
}
});
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//結果
s=0,s=2,s=4,
複製程式碼
Distinct
過濾排除重複的資料
Observable.just(1, 2, 4, 1, 2, 1)
.distinct()
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print("integer=" + integer + ",");
}
});
//結果
integer=1,integer=2,integer=4,
複製程式碼
ElementAt
只過濾傳送Observable中指定位置的資料
Observable.just(1, 2, 3, 4, 5)
.elementAt(3)
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print("integer=" + integer + ",");
}
});
//結果
ElementAt
integer=4,
複製程式碼
Filter
定義過濾函式來過濾傳送的資料
Observable.just(1, 2, 3, 4)
.filter(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer == 3||integer==4;
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print("integer=" + integer + ",");
}
});
//結果
integer=3,integer=4,
複製程式碼
First
過濾第一個資料或者符合過濾條件的第一個資料
Observable.just(1, 2, 3, 4)
.first(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer % 2 == 0;
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print("integer=" + integer + ",");
}
});
//結果
integer=2,
複製程式碼
Last
過濾最後一個資料或者符合過濾條件的最後一個資料
Observable.just(1, 2, 3, 4)
.last(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer % 2 == 0;
}
})
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print("integer=" + integer + ",");
}
});
//結果
integer=4,
複製程式碼
IgnoreElements
忽略不讓原Observable所有資料傳送,但允許傳送終止通知。如onError和onComplete
Observable
.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onNext(1);
subscriber.onCompleted();
subscriber.onNext(2);
subscriber.onNext(3);
}
})
.ignoreElements()
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
System.out.print("onCompleted");
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Integer integer) {
System.out.print("integer=" + integer + ",");
}
});
//結果
onCompleted
複製程式碼
Skip
跳過頭到第n個資料傳送
Observable.range(0, 10)
.skip(5)
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print("integer=" + integer + ",");
}
});
//結果
integer=5,integer=6,integer=7,integer=8,integer=9,
複製程式碼
SkipLast
跳過從尾數到第n個資料傳送
Observable.range(0, 10)
.skipLast(5)
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print("integer=" + integer + ",");
}
});
//結果
integer=0,integer=1,integer=2,integer=3,integer=4,
複製程式碼
Take
從頭開始過濾出n個資料傳送
Observable.range(0, 10)
.take(5)
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print("integer=" + integer + ",");
}
});
//結果
integer=0,integer=1,integer=2,integer=3,integer=4,
複製程式碼
TakeLast
從尾開始過濾出n個資料傳送
Observable.range(0, 10)
.takeLast(5)
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print("integer=" + integer + ",");
}
});
//結果
integer=5,integer=6,integer=7,integer=8,integer=9,
複製程式碼
組合
merge
合併兩個Observable的資料結果,順序不定(猜測是非同步傳送)
Observable<Long> interval1 = Observable.interval(100, TimeUnit.MILLISECONDS)
.map(new Func1<Long, Long>() {
@Override
public Long call(Long aLong) {
return aLong - 5L;
}
}).take(5);//抑制定時整數序列數量5個
Observable<Long> interval2 = Observable.interval(100, TimeUnit.MILLISECONDS).take(5);//抑制定時整數序列數量5個
Observable.merge(interval1, interval2).subscribe(new Action1<Number>() {
@Override
public void call(Number number) {
System.out.print(number + " ");
}
});
//結果
0 -5 -4 1 -3 2 -2 3 -1 4
複製程式碼
Concat
合併兩個Observable的資料結果,順序前後確定(同步傳送,第一個傳送完畢才會傳送第二個)
Observable<Long> interval1 = Observable.interval(100, TimeUnit.MILLISECONDS)
.map(new Func1<Long, Long>() {
@Override
public Long call(Long aLong) {
return aLong - 5L;
}
}).take(5);//抑制定時整數序列數量5個
Observable<Long> interval2 = Observable.interval(100, TimeUnit.MILLISECONDS).take(5);//抑制定時整數序列數量5個
Observable.concat(interval1, interval2).subscribe(new Action1<Number>() {
@Override
public void call(Number number) {
System.out.print(number + " ");
}
});
//結果
-5 -4 -3 -2 -1 0 1 2 3 4
複製程式碼
startWith
在observable的資料來源前面插入資料
Observable<Integer> range = Observable.range(0, 10);
range.startWith(-2, -1).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.print(integer + " ");
}
});
//結果
-2 -1 0 1 2 3 4 5 6 7 8 9
複製程式碼
zip
合併Observables的資料,使用發射的順序作為合併的標記 Javadoc: [zip(Iterable,FuncN) ](http://reactivex.io/RxJava/javadoc/rx/Observable.html# zip(java.lang.Iterable,%20rx.functions.FuncN)) Javadoc: [zip(Observable,FuncN) ](http://reactivex.io/RxJava/javadoc/rx/Observable.html# zip(rx.Observable,%20rx.functions.FuncN)) Javadoc: [zip(Observable,Observable,Func2)](http://reactivex.io/RxJava/javadoc/rx/Observable.html# zip(rx.Observable,%20rx.Observable,%20rx.functions.Func2)) (最多可以有九個Observables引數)
Observable<Long> interval5 = Observable.interval(100, TimeUnit.MILLISECONDS)
.map(new Func1<Long, Long>() {
@Override
public Long call(Long aLong) {
return aLong - 5L;
}
}).take(6);//抑制定時整數序列數量5個
Observable<Long> interval6 = Observable.interval(100, TimeUnit.MILLISECONDS).take(5);//抑制定時整數序列數量5個
Observable.zip(interval5, interval6, new Func2<Long, Long, String>() {
@Override
public String call(Long aLong, Long aLong2) {
return aLong + "~" + aLong2;
}
}).subscribe(new Action1<String>() {
@Override
public void call(String item) {
System.out.print(item + " ");
}
});
//結果
-5~0 -4~1 -3~2 -2~3 -1~4
複製程式碼
CombineLatest
根據每個Observable的傳送時間作為合併標記,任何一個Observable資料傳送之後就和其他的Observable最近傳送的資料進行合併。
Observable<Long> interval7 = Observable.interval(100, TimeUnit.MILLISECONDS)
.map(new Func1<Long, Long>() {
@Override
public Long call(Long aLong) {
return aLong - 5L;
}
}).take(6);//抑制定時整數序列數量5個
Observable<Long> interval8 = Observable.interval(200, TimeUnit.MILLISECONDS).take(5);//抑制定時整數序列數量5個
Observable.combineLatest(interval7, interval8, new Func2<Long, Long, String>() {
@Override
public String call(Long aLong, Long aLong2) {
return aLong + "~" + aLong2;
}
}).subscribe(new Action1<String>() {
@Override
public void call(String item) {
System.out.print(item + " ");
}
});
//結果
-4~0 -3~0 -3~1 -2~1 -1~1 -1~2 0~2 0~3 0~4
複製程式碼
join
合併的兩個Observable的資料,合併標記基於對Observable資料定義的生命週期,如果資料過了生命週期則就不會和其他Observable的資料進行合併,否則就排列組合形式合併。(如果不懂建議點選連結直接看圖)
Observable<Long> observable1 = Observable.interval(300, TimeUnit.MILLISECONDS).delay(400, TimeUnit.MILLISECONDS).take(5);//延遲1個多身位
Observable<Long> observable2 = Observable.interval(300, TimeUnit.MILLISECONDS).take(5);
observable1.join(observable2, new Func1<Long, Observable<Long>>() {
@Override
public Observable<Long> call(Long aLong) {
return Observable.just(aLong).delay(100, TimeUnit.MILLISECONDS);//每個資料100毫秒生命
}
}, new Func1<Long, Observable<Long>>() {
@Override
public Observable<Long> call(Long aLong) {
return Observable.just(aLong).delay(150, TimeUnit.MILLISECONDS);//每個資料150毫秒生命
}
}, new Func2<Long, Long, String>() {
@Override
public String call(Long aLong, Long aLong2) {
return "A-" + aLong + ":B-" + aLong2;
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
System.out.print(s+" ");
}
});
//結果
A-0:B-1 A-1:B-2 A-2:B-3 A-3:B-4
複製程式碼
錯誤處理
catch
攔截原始Observable的onError通知,將它替換為其它的資料項或資料序列,讓產生的Observable能夠正常終止或者根本不終止。
- [onErrorReturn](http://reactivex.io/RxJava/javadoc/rx/Observable.html# onErrorReturn(rx.functions.Func1)) 讓Observable遇到錯誤時發射一個特殊的項並且正常終止。
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onError(new IllegalAccessException("no access"));
}
}).onErrorReturn(new Func1<Throwable, Integer>() {
@Override
public Integer call(Throwable throwable) {
return 10001;
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
System.out.print("onError");
}
@Override
public void onNext(Integer integer) {
System.out.print("error_code:" + integer);
}
});
//結果
error_code:10001
複製程式碼
- [onErrorResumeNext](http://reactivex.io/RxJava/javadoc/rx/Observable.html# onErrorResumeNext(rx.functions.Func1)) 讓Observable在遇到錯誤時開始發射指定的第二個Observable的資料序列。
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onError(new IllegalAccessException("no access"));
}
}).onErrorResumeNext(new Func1<Throwable, Observable<? extends Integer>>() {
@Override
public Observable<? extends Integer> call(Throwable throwable) {
return Observable.just(1, 2);
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
System.out.print("onError");
}
@Override
public void onNext(Integer integer) {
System.out.print(",value:" + integer);
}
});
//結果
,value:1,value:2
複製程式碼
- [onExceptionResumeNext](http://reactivex.io/RxJava/javadoc/rx/Observable.html# onExceptionResumeNext(rx.Observable)) 和onErrorResumeNext類似,onExceptionResumeNext方法返回一個備用Observable,不同的是,如果onError收到的Throwable不是一個Exception,它會將錯誤傳遞給觀察者的onError方法,不會使用備用的Observable。
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onError(null);
}
}).onExceptionResumeNext(Observable.just(1, 2, 3, 4))
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
System.out.print("onError:");
}
@Override
public void onNext(Integer integer) {
System.out.print(",value:" + integer);
}
});
//結果
onError:
複製程式碼
重試
如果原始Observable遇到錯誤,重新訂閱它期望它能正常終止,資料會有部分重複。
- retry Javadoc: [retry()]([http://reactivex.io/RxJava/javadoc/rx/Observable.html# retry](http://reactivex.io/RxJava/javadoc/rx/Observable.html# retry)()) Javadoc: [retry(long)](http://reactivex.io/RxJava/javadoc/rx/Observable.html# retry(long))錯誤次數 Javadoc: [retry(Func2)](http://reactivex.io/RxJava/javadoc/rx/Observable.html# retry(rx.functions.Func2)) 異常判斷
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
subscriber.onError(new IllegalAccessException("IllegalAccessException"));
}
}).retry(new Func2<Integer, Throwable, Boolean>() {
@Override
public Boolean call(Integer integer, Throwable throwable) {
System.out.println("num:" + integer + " throwable:" + throwable.getMessage());
return !(throwable instanceof IllegalAccessException);
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
}
@Override
public void onError(Throwable e) {
System.out.println("onError:" + e.getMessage());
}
@Override
public void onNext(Integer integer) {
}
});
//結果
num:1 throwable:IllegalAccessException
onError:IllegalAccessException
複製程式碼
- [retrywhen](http://reactivex.io/RxJava/javadoc/rx/Observable.html# retryWhen(rx.functions.Func1)) 不太理解...(主要作用可以和retorfit一起用)
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
System.out.println("subscribing");
subscriber.onError(new RuntimeException("always fails"));
}
}).retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {
@Override
public Observable<?> call(Observable<? extends Throwable> observable) {
return observable.zipWith(Observable.range(1, 3), new Func2<Throwable, Integer, Integer>() {
@Override
public Integer call(Throwable throwable, Integer integer) {
return integer;
}
}).flatMap(new Func1<Integer, Observable<?>>() {
@Override
public Observable<?> call(Integer integer) {
System.out.println("delay retry by " + integer + " second(s)");
return Observable.timer(integer, TimeUnit.SECONDS);
}
});
}
}).toBlocking().forEach(new Action1<Object>() {
@Override
public void call(Object o) {
System.out.println("foreach:"+o);
}
});
//結果
subscribing
delay retry by 1 second(s)
subscribing
delay retry by 2 second(s)
subscribing
delay retry by 3 second(s)
subscribing
複製程式碼
除了這些還有輔助、條件和布林、算術和聚合、連線、轉換、操作符決策樹操作符 其他操作符太零散了,直接參考下面 中文翻譯 官網-操作符介紹 操作符doc文件