之前沒有了解過Rxjava的童鞋,建議先閱讀《Rxjava 從入門到開發》這篇文章,對入門比較有幫助。
map操作符
作用:通過call函數根據函數Func1<T,K>把T轉換為K
List<Student> students=new ArrayList<>();
Student stuent=new Student();
stuent.setName("小一");
Student s1=new Student();
s1.setName("小二");
students.add(stuent);
students.add(s1);
subscription=Observable.from(students).map(new Func1<Student, String>() {
@Override
public String call(Student student) {
return student.getName();
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
Logger.i("MapOperation : "+s);
}
});
輸出結果:
例子說明:通過map操作符,我們把輸入的Student對象轉換成了String變量,然后遍歷輸出。
flag map操作符
作用:對序列的每一項通過call函數根據函數Func1<T,Observable<K>>把T通過操作符轉換為K
Observable.just(10, 20, 30).flatMap(new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(Integer integer) {
//10的延遲執行時間為200毫秒、20和30的延遲執行時間為180毫秒
int delay = 200;
if (integer > 10)
delay = 180;
return Observable.from(new Integer[]{integer, integer / 2}).delay(delay, TimeUnit.MILLISECONDS);
}
}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println("flatMap Next:" + integer);
}
});
輸出結果:
例子說明:輸入數字10,20,30通過操作符from和delay輸出,這里要注意的是,輸出結果已經出現了亂序,即沒有按照10,5;20,10;30,15的順序輸出。
concatMap操作符
作用:對序列的每一項通過call函數根據函數Func1<T,Observable<K>>把T通過操作符轉換為K,相對于flatmap可以保證輸出順序一致
Observable.just(10, 20, 30).concatMap(new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(Integer integer) {
//10的延遲執行時間為200毫秒、20和30的延遲執行時間為180毫秒
int delay = 200;
if (integer > 10)
delay = 180;
return Observable.from(new Integer[]{integer, integer / 2}).delay(delay, TimeUnit.MILLISECONDS);
}
}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println("concatMap Next:" + integer);
}
});
輸出結果:
例子說明:輸入數字10,20,30通過操作符from和delay輸出,這里要注意的是,輸出結果沒有出現亂序
switchMap操作符
作用:對序列的每一項通過call函數根據函數Func1<T,Observable<K>>把T通過操作符轉換為K,若結果k1,k2同時出現則則會保留最新的k2,丟棄k1
Observable.just(10, 20, 30).switchMap(new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(Integer integer) {
//10的延遲執行時間為200毫秒、20和30的延遲執行時間為180毫秒
int delay = 200;
if (integer > 10)
delay = 180;
return Observable.from(new Integer[]{integer, integer / 2}).delay(delay, TimeUnit.MILLISECONDS);
}
}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println("switchMap Next:" + integer);
}
});
輸出結果:
例子說明:輸入數字10,20,30通過操作符from和delay輸出,但是由于switchmap操作符的作用,10的輸出被20覆蓋,20的輸出結果被30覆蓋,故最后只有30,15輸出。
以上demo 出自Android RxJava使用介紹(三) RxJava的操作符,最后總結下map,flatmap,contactmap,switchmap的使用場景區別:map用于不需要通過操作符就可以完成的轉換,flatmap用于需要通過操作符才可以轉換的操作,但是輸出結果可能會是亂序,contactmap的作用在flatmap的基礎上保證輸出結果按照輸入順序輸出,switchmap的作用在flatmap的基礎上,對輸出結果若同時發生,只會保證最新結果而放棄舊數據。
Scan操作符
作用:連續地對數據序列的每一項應用一個函數,然后連續發射結果
Integer numbers[]={1,2,3,4,5,};
Observable observable=Observable.from(numbers);
subscription=observable.scan(new Func2<Integer,Integer,Integer>() {
@Override
public Integer call(Integer sum, Integer item) {
System.out.println(" sum: "+sum+" item: "+item);
return sum+item;
}
})
.subscribe(new Action1() {
@Override
public void call(Object o) {
System.out.println(" number: "+o);
}
});
SubscriptionManager.setSubscription(subscription);
輸出結果:
例子說明:這里要注意的是變量sum等于輸入數相加,item為某項輸入,例如:現在輸入的是3,即item為3,sum則為1和2相加的結果,最后返回的是3+3等6,下一步輸入item為4,則sum為6,接下來返回的便是6+4的結果。
groupBy操作符
作用:可以對輸入的數據根據自定義類型分組
Observable.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
for(int i=0;i<6;i++){
int number=random.nextInt(10);
System.out.println("key: " + number);
subscriber.onNext(number);
}
}
}).groupBy(new Func1<Integer, String>() {
@Override
public String call(Integer value) {
return value % 2 == 0 ? "偶數" : "奇數";
}
}).subscribe(new Action1<GroupedObservable<String, Integer>>() {
@Override
public void call(final GroupedObservable<String, Integer> stringIntegerGroupedObservable) {
stringIntegerGroupedObservable.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println("key:" + stringIntegerGroupedObservable.getKey() +", value:" + integer);
}
});
}
});
輸出結果:
例子說明:輸入六個隨機數8,1,2,8,7,8,結果我原以為數據會先輸出偶數項,再輸出奇數項,但是結果卻是輸出數據的順序和輸入一致,但是通過GroupedObservable.getkey 方法可以獲取數據所屬分類。另外這里需要注意的是:groupBy將原始Observable分解為一個發射多個GroupedObservable的Observable,一旦有訂閱,每個GroupedObservable就開始緩存數據。因此,如果你忽略這些GroupedObservable中的任何一個,這個緩存可能形成一個潛在的內存泄露。因此,如果你不想觀察,也不要忽略GroupedObservable。你應該使用像take(0)這樣會丟棄自己的緩存的操作符。
Buffer操作符
作用:定期收集Observable的數據放進一個數據包裹,然后發射這些數據包裹,而不是一次發射一個值。
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
final String[] names = {"小-", "小二", "小三", "小四", "小五"};
Random random = new Random();
if(subscriber.isUnsubscribed()){
return;
}
do {
String name = names[random.nextInt(names.length)];
subscriber.onNext(name);
try {
Thread.sleep(1000);
}catch (Exception e){
e.printStackTrace();
}
} while (true);
}
}).subscribeOn(Schedulers.io()).buffer(2,TimeUnit.SECONDS).subscribe(new Action1<List<String>>() {
@Override
public void call(List<String> strings) {
System.out.println("開始兩秒點一次名字...");
for (String name:strings) {
System.out.println("name: "+name);
}
}
});
輸出結果:
例子說明:create操作符里面一直在做每隔1秒就發送一個隨機名字的操作,通過buffer操作符可以實現每隔2秒輸出一組名字。
Window操作符
作用:和buffer類似作用類似,但是輸出的是Observable而不是具體數據
Observable.interval(1, TimeUnit.SECONDS).take(10).
window(2,TimeUnit.SECONDS).subscribe(new Action1<Observable<Long>>() {
@Override
public void call(Observable<Long> longObservable) {
System.out.println("每隔兩秒打印.....");
longObservable.subscribe(new Action1<Long>() {
@Override
public void call(Long aLong) {
System.out.println("currentNumber: "+aLong);
}
});
}
});
輸出結果:
例子說明:interval操作符表示按照順序和預期時間輸出一個0-n的數列,例如:0,1,2...n, take操作符表示截取前n個結果集,在例子中就是截取interval操作符輸出的0-9共10個數,** window操作符作用和buffer差不多,不同的是buffer輸出具體的數值,但是Window輸出的Observable,需要再進一步訂閱才能輸出具體數值**。
Cast操作符
作用:對數據進行強轉類型
但是實際使用中本人發現僅僅能用于對輸入數據的類型判斷是否符合預期
String[] strs=new String[]{"1","2","3","4","5"};
subscription=Observable.from(strs).observeOn(Schedulers.io()).cast(Integer.class).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println("integer: " + integer);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
throwable.printStackTrace();
}
});
輸出結果:
例子說明:輸入類型正確則輸出源數據,如果輸入數據某項內容類型不正確,則報錯。
以上便是變換操作符的主要內容了。有啥問題歡迎大家留言交流下??,下篇文章再說說過濾操作符歡迎關注。
附錄:
文章demo