這個頁面展示了可用於對Observable發射的數據執行變換操作的各種操作符。
變換操作
map( ) — 對序列的每一項都應用一個函數來變換Observable發射的數據序列
flatMap( ), concatMap( ), and flatMapIterable( ) — 將Observable發射的數據集合變換爲Observables集合,然後將這些Observable發射的數據平坦化的放進一個單獨的Observable
switchMap( ) — 將Observable發射的數據集合變換爲Observables集合,然後只發射這些Observables最近發射的數據
scan( ) — 對Observable發射的每一項數據應用一個函數,然後按順序依次發射每一個值
groupBy( ) — 將Observable分拆爲Observable集合,將原始Observable發射的數據按Key分組,每一個Observable發射一組不同的數據
buffer( ) — 它定期從Observable收集數據到一個集合,然後把這些數據集合打包發射,而不是一次發射一個
window( ) — 定期將來自Observable的數據分拆成一些Observable窗口,然後發射這些窗口,而不是每次發射一項
cast( ) — 在發射之前強制將Observable發射的所有數據轉換爲指定類型
map–一對一變換
private Observable<String> processUrlsIpByMap() {
return Observable.just(
"發送just")
.map(new Func1<String, String>() {
@Override
public String call(String s) {
try {
return s + " : " + "map修改";
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (UnknownHostException e) {
e.printStackTrace();
}
return null;
}
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
printLog(tvLogs, "Consume Data: ", s);
}
});
}
結果
發送just:map修改
flatmap–一轉多
flatmap對於新入門的來說,理解起來確實有一定的難度,可以先看一個簡單的栗子:
Subscriber subcriber = new Subscriber<Integer>() {
@Override
public void onCompleted() {
Log.d(TAG, "onCompleted: Completed!");
}
@Override
public void onError(Throwable e) {
Log.d(TAG, "onError: Error!");
}
@Override
public void onNext(Integer integer) {
Log.d(TAG, "onNext: " + integer);
}
};
Observable.just("1", "2", "3", "4")
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.flatMap(new Func1<String, Observable<Integer>>() {
@Override
public Observable<Integer> call(String s) {
return Observable.just(Integer.parseInt(s)+1);
}
})
.subscribe(subcriber);
從上面我們可以看出,map與flatmap很相似,都是用的Func1,而且模式都是I,O模式,即是:I轉換成O並返回。但是最大的不同點在於:我們flatmap的輸出類型是Observable的類型。
在這裏請注意一個問題:在執行flatmap中返回之後(O輸出返回的Observable),並不是立馬把返回的Observable通過Subscribe進行訂閱,而是將返回的若干Observables都交給同一個Observable,然後再進行subscribe。
所以,在上面我們先將字符串”1″,”2″, “3”, “4” 分別轉換成一個整形的Observable類型,即是:Observable(2),Observable(3),Observable(4),Observable(5)。然後將這些個Observables統一轉換成一個Observable,再進行subscribe。看一下結果:
onNext: 2
onNext: 3
onNext: 4
onNext: 5
onCompleted: Completed!
那麼,這個flatmap到底有何用呢?可以用在什麼地方呢?
假設這樣一種情景:一個學校的老師我們定義爲一個集合A,每個老師包括了個人信息和所教課程,一個老師不可能只教授一門課程,所以我們將老師所教授課程定義爲集合B。如果讓你打印每個老師所教課程,該怎麼做?
Teacher[] teachers = ...;
Subscriber<Course> subscriber = new Subscriber<Course>() {
@Override
public void onNext(Course course) {
Log.d(tag, course.getName());
}
...
};
Observable.from(teachers)
.flatMap(new Func1<Teacher, Observable<Course>>() {
@Override
public Observable<Course> call(Teacher teacher) {
return Observable.from(teacher.getCourses());
}
})
.subscribe(subscriber);
最後再補充一點:FlatMap對這些Observables發射的數據做的是合併(merge)操作,因此它們可能是交錯的。這意味着flatMap()函數在最後的Observable中不能夠保證源Observables確切的發射順序。