這篇章主要介紹Rxjava的變換操作符
目錄
Buffer
Buffer
操作符將一個Observable變換爲另一個,原來的Observable正常發射數據,變換產生的Observable發射這些數據的緩存集合。這是中文幫助文檔的解釋,先看代碼,我再按自己的瞭解描述一次
Observable.just(1,2,3,4,5,6,7,8,9).buffer(3).subscribe(new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integers) throws Exception {
System.out.println("--size:" + integers.size());
for (int integer : integers) {
System.out.println("--value:" + integer);
}
}
});
結果:
--size:3
--value:1
--value:2
--value:3
--size:3
--value:4
--value:5
--value:6
--size:3
--value:7
--value:8
--value:9
buffer裏面傳入3,其實就是把本來Observable.just創建出來的Observable轉換成一個新的Observable,而這個新的Observable就是以原數據每三個作爲一個列表發射出去而已。
Observable.just(1,2,3,4,5,6,7,8,9).buffer(3, 2).subscribe(new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integers) throws Exception {
System.out.println("--size:" + integers.size());
for (int integer : integers) {
System.out.println("--value:" + integer);
}
}
});
結果:
--size:3
--value:1
--value:2
--value:3
--size:3
--value:3
--value:4
--value:5
--size:3
--value:5
--value:6
--value:7
--size:3
--value:7
--value:8
--value:9
--size:1
--value:9
buffer.(3,2),一參爲每次發射列表的個數,二參爲每次取列表所跳過的個數,如上面結果所示,第一個列表爲1,2,3,然後跳過兩個,所以第二個列表取到的是3,4,5了。其實上面只傳一個參數buffer(3)的寫法,就相當於buffer(?,?),?是什麼呢,你在評論裏回答,這樣都回答不出,怎麼面對你的列祖列宗。沒錯答案就是buffer(3,3)。
FlatMap
FlatMap
將一個發射數據的Observable變換爲多個Observables,然後將它們發射的數據合併後放進一個單獨的Observable。
根據文檔說法和下面的圖,其實個人理解就是你發射了一組三個數據的,而每個數據經過flatMap的雨露恩澤後,都變成了一個新的Observable,而每個Observable會重新訂閱即subscribe你原來Observable本來subscribe的那個傢伙(那個observer觀察者)。我寫完都不知自己在說什麼,都說了看代碼是最好的。
Observable.just(1,2,3).flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Throwable {
List<Integer> list = new ArrayList<>();
for (int i = 0; i < integer; i++){
list.add(integer);
}
return Observable.fromIterable(list).map(num -> num+"+");
}
}).subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(String s) {
System.out.println(s+"*");
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
System.out.println("完成");
}
});
結果:
1+*
2+*
2+*
3+*
3+*
3+*
完成
flatmap產生的每個新的Observable只會調用觀察者的onNext,所有完成纔會調用onComplete
GroupBy
將一個Observable分拆爲一些Observables集合,它們中的每一個發射原始Observable的一個子序列。看代碼
String[] strs = {"同調怪獸", "永續魔法", "速攻魔法", "超量怪獸", "儀式怪獸", "反擊陷阱", "場地魔法", "永續陷阱"};
Observable.fromArray(strs).groupBy(s -> {
if (s.contains("怪獸")) {
return "怪獸";
}
else if (s.contains("魔法")) {
return "魔法";
}
else {
return "陷阱";
}
}).subscribe(new Observer<GroupedObservable<String, String>>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(GroupedObservable<String, String> groupedObservable) {
groupedObservable.subscribe(new Observer<String>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(String s) {
System.out.println(groupedObservable.getKey() + "組: " + s);
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
System.out.println(groupedObservable.getKey() + "組完成");
}
});
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
System.out.println("全部完成");
}
});
結果:
怪獸組: 同調怪獸
魔法組: 永續魔法
魔法組: 速攻魔法
怪獸組: 超量怪獸
怪獸組: 儀式怪獸
陷阱組: 反擊陷阱
魔法組: 場地魔法
陷阱組: 永續陷阱
魔法組完成
怪獸組完成
陷阱組完成
全部完成
groupby後的Observable要訂閱放了GroupedObservable<T, E>的觀察者observer,T其實就是每一組的key,我上面是根據這樣分key的。
if (s.contains("怪獸")) {
return "怪獸";
}
else if (s.contains("魔法")) {
return "魔法";
}
else {
return "陷阱";
}
而E就是跟原來要發射的數據同類型。groupby其實就是把本來的數據,每一個轉換成GroupedObservable<T, E>,而這個GroupedObservable也是Observable來的,所以Observable的操作符它都能用。
Map
看代碼
Observable.just(1,2,3).map(num -> num+"+").subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Throwable {
System.out.println(s+"*");
}
});
結果:
1+*
2+*
3+*
說白就是,把你本來發射的數據,經過一個函數得到新的值再發射出去。看到map的時候,我一直在想,我寫一個函數方法出來,然後把我的數組經過我的函數得到新的數組再扔個just,不是一樣的效果嗎。或是在onNext的時候得到的數據先經過我寫的函數方法,再打印出來,不也是一樣嗎。
那爲啥要有個map操作符。
這就是你跟別人的差距啦。人家用map就可以鏈式的寫法,看起來代碼就比較玲瓏浮凸,而且可以非常容易看到轉換的代碼在哪裏,都做了什麼轉換。除了這些,其實我還真沒想到用這個map還有什麼好地方。
Cast
Person[] people = {new Student("aaa"), new Student("bbb"), new Student("ccc")};
Observable.fromArray(people).cast(Student.class).subscribe(new Consumer<Student>() {
@Override
public void accept(Student student) throws Throwable {
System.out.println(student.getName()+"+");
}
});
結果也不貼出來了,其實很簡單這個。不是我不想打字,代碼就能解析清楚的事情,寫一遍論文幹什麼。Cast就是把發送的數據強轉爲另外一個類型,當然上面的Person類要是Student類的父類纔行啦。
Scan
Scan
操作符對原始Observable發射的第一項數據應用一個函數,然後將那個函數的結果作爲自己的第一項數據發射。它將函數的結果同第二項數據一起填充給這個函數來產生它自己的第二項數據。這個不粘貼給你看,可能有點難理解。
Observable.just(1, 2, 3, 4, 5).scan(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer sum, Integer item) throws Throwable {
return sum+item;
}
}).subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(Integer s) {
System.out.println(s+"*");
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
System.out.println("完成");
}
});
結果
1*
3*
6*
10*
15*
完成
上面1,3,6,10,15實際要發射給觀察者observer的數據。過程就是先發射原數據第一個數據,然後要發射的數據二是根據剛剛發射的數據和數據二進行你寫的函數得到的。那要發射的數據三就是剛剛發射的數據和數據三運算得到了羅……。
Window
定期將來自原始Observable的數據分解爲一個Observable窗口,發射這些窗口,而不是每次發射一項數據
Observable.just(1,2,3,4,5,6,7,8,9).window(3).subscribe(new Observer<Observable<Integer>>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(Observable<Integer> integerObservable) {
integerObservable.subscribe(new Observer<Integer>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(Integer integer) {
System.out.println(integer+"*");
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
System.out.println("裏面完成");
}
});
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
System.out.println("全部完成");
}
});
結果:
1*
2*
3*
裏面完成
4*
5*
6*
裏面完成
7*
8*
9*
裏面完成
全部完成
上面的代碼效果跟buffer(3)效果有點像,buffer是什麼?就在上面就在上面,翻上去看一下,再下來。不過就是buffer,是根據原數據分組成幾個列表發射給observer。而window即是把原數據分組成一個個Observable。上面的代碼你就可以理解爲把原數據分成了Observable.just(1,2,3),Observable.just(4,5,6),Observable.just(7,8,9)。如果用window就可以把數據轉成Observable,那你有可以爲所欲爲啦。