鍍金池/ 教程/ Android/ 有且僅有一次
combineLatest
從列表創(chuàng)建一個Observable
RxJava的與眾不同之處
Schedulers
RxJava觀察者模式工具包
總結(jié)
工具
你什么時候使用觀察者模式?
GroupBy
App架構(gòu)
組合Observables
創(chuàng)建Activity類
StartWith
RX - 從.NET到RxJava
處理耗時的任務(wù)
過濾Observables
向響應(yīng)式世界問好
避免阻塞I/O的操作
Join
有且僅有一次
Schedulers-解決Android主線程問題
轉(zhuǎn)換Observables
啟動引擎
我們的第一個Observable
總結(jié)
StrictMode
Debounce
*map家族
創(chuàng)建RecyclerView Adapter
為什么是Observables?
Merge
再多幾個例子
總結(jié)
Buffer
Window
總結(jié)
Timeout
執(zhí)行網(wǎng)絡(luò)任務(wù)
項目目標(biāo)
來到Java世界 - Netflix RxJava
獲取我們需要的數(shù)據(jù)
Observable
過濾序列
非阻塞I/O操作
ZIP
總結(jié)
And,Then和When
觀察者模式
Retrofit
Cast
Skip and SkipLast
微軟響應(yīng)式擴(kuò)展
與REST無縫結(jié)合-RxJava和Retrofit
First and last
RxJava Essentials 中文翻譯版
Switch
ElementAt
總結(jié)
總結(jié)
總結(jié)
Sampling
SubscribeOn and ObserveOn
Subject = Observable + Observer

有且僅有一次

一個可觀測序列會在出錯時重復(fù)發(fā)射或者被設(shè)計成重復(fù)發(fā)射。distinct()distinctUntilChanged()函數(shù)可以方便的讓我們處理這種重復(fù)問題。

Distinct

如果我們想對一個指定的值僅處理一次該怎么辦?我們可以對我們的序列使用distinct()函數(shù)去掉重復(fù)的。就像takeLast()一樣,distinct()作用于一個完整的序列,然后得到重復(fù)的過濾項,它需要記錄每一個發(fā)射的值。如果你在處理一大堆序列或者大的數(shù)據(jù)記得關(guān)注內(nèi)存使用情況。

下圖展示了如何在一個發(fā)射1和2兩次的可觀測源上創(chuàng)建一個無重的序列: http://wiki.jikexueyuan.com/project/rxjava/images/chapter4_5.png" alt="" />

為了創(chuàng)建我們例子中序列,我們將使用我們至今已經(jīng)學(xué)到的幾個方法:

  • take():它有一小組的可識別的數(shù)據(jù)項。
  • repeat():創(chuàng)建一個有重復(fù)的大的序列。

然后,我們將應(yīng)用distinct()函數(shù)來去除重復(fù)。

注意

我們用程序?qū)崿F(xiàn)一個重復(fù)的序列,然后過濾出它們。這聽起來時不可思議的,但是為了實現(xiàn)這個例子來使用我們至今為止已學(xué)習(xí)到的東西則是個不錯的練習(xí)。

Observable<AppInfo> fullOfDuplicates = Observable.from(apps)
    .take(3)
    .repeat(3);

fullOfDuplicates變量里把我們已安裝應(yīng)用的前三個重復(fù)了3次:有9個并且許多重復(fù)的。然后,我們使用distinct():

fullOfDuplicates.distinct()
            .subscribe(new Observer<AppInfo>() {

                @Override
                public void onCompleted() {
                    mSwipeRefreshLayout.setRefreshing(false);
                }

                @Override
                public void onError(Throwable e) {
                    Toast.makeText(getActivity(), "Something went wrong!", Toast.LENGTH_SHORT).show();
                    mSwipeRefreshLayout.setRefreshing(false);
                }

                @Override
                public void onNext(AppInfo appInfo) {
                    mAddedApps.add(appInfo); 
                    mAdapter.addApplication(mAddedApps.size() - 1,appInfo);
                }
            });
}

結(jié)果,很明顯,我們得到:

http://wiki.jikexueyuan.com/project/rxjava/images/chapter4_6.png" alt="" />

DistinctUntilsChanged

如果在一個可觀測序列發(fā)射一個不同于之前的一個新值時讓我們得到通知這時候該怎么做?我們猜想一下我們觀測的溫度傳感器,每秒發(fā)射的室內(nèi)溫度:

21°...21°...21°...21°...22°...

每次我們獲得一個新值,我們都會更新當(dāng)前正在顯示的溫度。我們出于系統(tǒng)資源保護(hù)并不想在每次值一樣時更新數(shù)據(jù)。我們想忽略掉重復(fù)的值并且在溫度確實改變時才想得到通知。ditinctUntilChanged()過濾函數(shù)能做到這一點。它能輕易的忽略掉所有的重復(fù)并且只發(fā)射出新的值。

下圖用圖形化的方式展示了我們?nèi)绾螌?code>distinctUntilChanged()函數(shù)應(yīng)用在一個存在的序列上來創(chuàng)建一個新的不重復(fù)發(fā)射元素的序列。

http://wiki.jikexueyuan.com/project/rxjava/images/chapter4_7.png" alt="" />