RxJava學習筆記 -- 過濾Observables

注:本文摘自《RxJava Essentials》翻譯中文版電子書

過濾序列

使用filter()方法來過濾我們觀測序列中不想要的值。只要條件符合filter()函數(shù)就會返回true饥侵。例如:

//過濾,只要C開頭的
.filter(new Func1<AppInfo,Boolean>(){
    @Override
    public Boolean call(AppInfo appInfo){
        return appInfo.getName().startsWith("C");
    }
})
//過濾null的對象
.filter(new Func1<AppInfo,Boolean>(){
    @Override
    public Boolean call(AppInfo appInfo){
        return appInfo != null;
    }
})

獲取我們需要的數(shù)據(jù)

如果只想取開頭或結尾的幾個元素,我們可以用take()或takeLast():

//獲取一個可觀測序列中的前三個元素
private void loadList(List<AppInfo> apps) {
    Observable.from(apps)
            .take(3)
            .subscribe(/**代碼省略**/);
}
//獲取最后N個元素
Observable.from(apps)
        .takeLast(3)
        .subscribe(...);

有且僅有一次

Distinct

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

Observable<AppInfo> fullOfDuplicates = Observable.from(apps) .take(3) .repeat(3);
  • take():它有一小組的可識別的數(shù)據(jù)項。
  • repeat():創(chuàng)建一個有重復的大的序列乏屯。

fullOfDuplicates 變量里把我們已安裝應用的前三個重復了3次:有9個并且許多重復的根时。然后,我們使用distinct()函數(shù)來去除重復:

fullOfDuplicates.distinct().subscribe(...);
DistinctUntilsChanged

引出問題:
如果在一個可觀測序列發(fā)射一個不同于之前的一個新值時讓我們得到通知這時候該怎么做辰晕?我們猜想一下我們觀測的溫度傳感器蛤迎,每秒發(fā)射的室內溫度:
21°...21°...21°...21°...22°...

每次我們獲得一個新值,我們都會更新當前正在顯示的溫度含友。我們出于系統(tǒng)資源保護并不想在每次值一樣時更新數(shù)據(jù)替裆。我們想忽略掉重復的值并且在溫度確實改變時才想得到通知。

ditinctUntilChanged()過濾函數(shù)能做到這一點窘问。它能輕易的忽略掉所有的重復并且只發(fā)射出新的值辆童。

First and last

從一個從可觀測源序列中創(chuàng)建只發(fā)射第一個元素的序列。
first()方法和last()方法很容易弄明白惠赫。它們從Observable中只發(fā)射第一個元素或者最后一個元素胸遇。

與first()和last()相似的變量有:firstOrDefault()和lastOrDefault()。這兩個函數(shù)當可觀測序列完成時不再發(fā)射任何值時用得上汉形。在這種場景下,如果Observable不再發(fā)射任何值時我們可以指定發(fā)射一個默認的值倍阐。

Skip and SkipLast

創(chuàng)建一個不發(fā)射前N個元素而是發(fā)射它后面的那些數(shù)據(jù)的序列或者跳過后面N個元素從源序列中發(fā)射剩下的其他元素概疆。

skip()和skipLast()函數(shù)與take()和takeLast()相對應。它們用整數(shù)N作參數(shù)峰搪,從本質上來說岔冀,它們不讓Observable發(fā)射前N個或者后N個值。如果我們知道一個序列以沒有太多用的“可控”元素開頭或結尾時我們可以使用它概耻。

ElementAt

如果我們只想要可觀測序列發(fā)射的第五個元素該怎么辦使套?elementAt()函數(shù)僅從一個序列中發(fā)射第n個元素然后就完成了罐呼。

如果我們想查找第五個元素但是可觀測序列只有三個元素可供發(fā)射時該怎么辦?我們可以使用elementAtOrDefault()侦高。

Sampling

回到那個溫度傳感器問題嫉柴,每秒都會發(fā)射當前室內的溫度。說實話奉呛,我們并不認為溫度會變化這么快计螺,我們可以使用一個小的發(fā)射間隔。在Observable后面加一個sample()瞧壮,我們將創(chuàng)建一個新的可觀測序列登馒,它將在一個指定的時間間隔里由Observable發(fā)射最近一次的數(shù)值:

Observable<Integer> sensor = [...]
sensor.sample(30,TimeUnit.SECONDS)
    .subscribe(...);

上面例子Observable將會觀測溫度Observable然后每隔30秒就會發(fā)射最后一個溫度值。sample()支持全部的時間單位:秒咆槽,毫秒陈轿,天,分等等秦忿。
下圖中展示了一個間隔發(fā)射字母的Observable如何采樣一個發(fā)射數(shù)字的Observable麦射。Observable的結果將會發(fā)射每個已發(fā)射字母的最后一組數(shù)據(jù):1,4小渊,5.


sample.png

如果我們想讓它定時發(fā)射第一個元素而不是最近的一個元素法褥,我們可以使用throttleFirst()

Timeout

假設我們工作的是一個時效性的環(huán)境,我們溫度傳感器每秒都在發(fā)射一個溫度值酬屉。我們想讓它每隔兩秒至少發(fā)射一個半等,我們可以使用timeout()函數(shù)來監(jiān)聽源可觀測序列,就是在我們設定的時間間隔內如果沒有得到一個值則發(fā)射一個錯誤。我們可以認為timeout()為一個Observable的限時的副本呐萨。如果在指定的時間間隔內Observable不發(fā)射值的話杀饵,它監(jiān)聽的原始的Observable時就會觸發(fā)onError()函數(shù)。

Subscription subscription = getCurrentTemperature()
    .timeout(2,TimeUnit.SECONDS)
    .subscribe(...);

Debounce

debounce()函數(shù)過濾掉由Observable發(fā)射的速率過快的數(shù)據(jù)谬擦;如果在一個指定的時間間隔過去了仍舊沒有發(fā)射一個切距,那么它將發(fā)射最后的那個。
就像sample()和timeout()函數(shù)一樣惨远,debounce()使用TimeUnit對象指定時間間隔谜悟。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市北秽,隨后出現(xiàn)的幾起案子葡幸,更是在濱河造成了極大的恐慌,老刑警劉巖贺氓,帶你破解...
    沈念sama閱讀 222,681評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蔚叨,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機蔑水,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,205評論 3 399
  • 文/潘曉璐 我一進店門邢锯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人搀别,你說我怎么就攤上這事丹擎。” “怎么了领曼?”我有些...
    開封第一講書人閱讀 169,421評論 0 362
  • 文/不壞的土叔 我叫張陵鸥鹉,是天一觀的道長。 經(jīng)常有香客問我庶骄,道長毁渗,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 60,114評論 1 300
  • 正文 為了忘掉前任单刁,我火速辦了婚禮灸异,結果婚禮上,老公的妹妹穿的比我還像新娘羔飞。我一直安慰自己肺樟,他們只是感情好,可當我...
    茶點故事閱讀 69,116評論 6 398
  • 文/花漫 我一把揭開白布逻淌。 她就那樣靜靜地躺著么伯,像睡著了一般。 火紅的嫁衣襯著肌膚如雪卡儒。 梳的紋絲不亂的頭發(fā)上田柔,一...
    開封第一講書人閱讀 52,713評論 1 312
  • 那天,我揣著相機與錄音骨望,去河邊找鬼硬爆。 笑死,一個胖子當著我的面吹牛擎鸠,可吹牛的內容都是我干的缀磕。 我是一名探鬼主播,決...
    沈念sama閱讀 41,170評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼劣光,長吁一口氣:“原來是場噩夢啊……” “哼袜蚕!你這毒婦竟也來了?” 一聲冷哼從身側響起绢涡,我...
    開封第一講書人閱讀 40,116評論 0 277
  • 序言:老撾萬榮一對情侶失蹤牲剃,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后垂寥,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,651評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,714評論 3 342
  • 正文 我和宋清朗相戀三年滞项,在試婚紗的時候發(fā)現(xiàn)自己被綠了狭归。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,865評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡文判,死狀恐怖过椎,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情戏仓,我是刑警寧澤疚宇,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站赏殃,受9級特大地震影響敷待,放射性物質發(fā)生泄漏。R本人自食惡果不足惜仁热,卻給世界環(huán)境...
    茶點故事閱讀 42,211評論 3 336
  • 文/蒙蒙 一榜揖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧抗蠢,春花似錦举哟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,699評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至秽褒,卻和暖如春壶硅,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背震嫉。 一陣腳步聲響...
    開封第一講書人閱讀 33,814評論 1 274
  • 我被黑心中介騙來泰國打工森瘪, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人票堵。 一個月前我還...
    沈念sama閱讀 49,299評論 3 379
  • 正文 我出身青樓扼睬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親悴势。 傳聞我的和親對象是個殘疾皇子窗宇,可洞房花燭夜當晚...
    茶點故事閱讀 45,870評論 2 361

推薦閱讀更多精彩內容