RXJava 變換操作

這個頁面展示了可用於對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確切的發射順序。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章