RxJava学习笔记 -- 过滤Observables

注:本文摘自《RxJava Essentials》翻译中文版电子书

过滤序列

使用filter()方法来过滤我们观测序列中不想要的值。只要条件符合filter()函数就会返回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;
    }
})

获取我们需要的数据

如果只想取开头或结尾的几个元素,我们可以用take()或takeLast():

//获取一个可观测序列中的前三个元素
private void loadList(List<AppInfo> apps) {
    Observable.from(apps)
            .take(3)
            .subscribe(/**代码省略**/);
}
//获取最后N个元素
Observable.from(apps)
        .takeLast(3)
        .subscribe(...);

有且仅有一次

Distinct

如果我们想对一个指定的值仅处理一次该怎么办?我们可以对我们的序列使用distinct()
函数去掉重复的。就像takeLast()一样,distinct()作用于一个完整的序列,然后得到重复的过滤项,它需要记录每一个发射的值。如果你在处理一大堆序列或者大的数据记得关注内存使用情况。
例子:

Observable<AppInfo> fullOfDuplicates = Observable.from(apps) .take(3) .repeat(3);
  • take():它有一小组的可识别的数据项。
  • repeat():创建一个有重复的大的序列。

fullOfDuplicates 变量里把我们已安装应用的前三个重复了3次:有9个并且许多重复的。然后,我们使用distinct()函数来去除重复:

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

引出问题:
如果在一个可观测序列发射一个不同于之前的一个新值时让我们得到通知这时候该怎么做?我们猜想一下我们观测的温度传感器,每秒发射的室内温度:
21°...21°...21°...21°...22°...

每次我们获得一个新值,我们都会更新当前正在显示的温度。我们出于系统资源保护并不想在每次值一样时更新数据。我们想忽略掉重复的值并且在温度确实改变时才想得到通知。

ditinctUntilChanged()过滤函数能做到这一点。它能轻易的忽略掉所有的重复并且只发射出新的值。

First and last

从一个从可观测源序列中创建只发射第一个元素的序列。
first()方法和last()方法很容易弄明白。它们从Observable中只发射第一个元素或者最后一个元素。

与first()和last()相似的变量有:firstOrDefault()和lastOrDefault()。这两个函数当可观测序列完成时不再发射任何值时用得上。在这种场景下,如果Observable不再发射任何值时我们可以指定发射一个默认的值。

Skip and SkipLast

创建一个不发射前N个元素而是发射它后面的那些数据的序列或者跳过后面N个元素从源序列中发射剩下的其他元素。

skip()和skipLast()函数与take()和takeLast()相对应。它们用整数N作参数,从本质上来说,它们不让Observable发射前N个或者后N个值。如果我们知道一个序列以没有太多用的“可控”元素开头或结尾时我们可以使用它。

ElementAt

如果我们只想要可观测序列发射的第五个元素该怎么办?elementAt()函数仅从一个序列中发射第n个元素然后就完成了。

如果我们想查找第五个元素但是可观测序列只有三个元素可供发射时该怎么办?我们可以使用elementAtOrDefault()。

Sampling

回到那个温度传感器问题,每秒都会发射当前室内的温度。说实话,我们并不认为温度会变化这么快,我们可以使用一个小的发射间隔。在Observable后面加一个sample(),我们将创建一个新的可观测序列,它将在一个指定的时间间隔里由Observable发射最近一次的数值:

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

上面例子Observable将会观测温度Observable然后每隔30秒就会发射最后一个温度值。sample()支持全部的时间单位:秒,毫秒,天,分等等。
下图中展示了一个间隔发射字母的Observable如何采样一个发射数字的Observable。Observable的结果将会发射每个已发射字母的最后一组数据:1,4,5.


sample.png

如果我们想让它定时发射第一个元素而不是最近的一个元素,我们可以使用throttleFirst()

Timeout

假设我们工作的是一个时效性的环境,我们温度传感器每秒都在发射一个温度值。我们想让它每隔两秒至少发射一个,我们可以使用timeout()函数来监听源可观测序列,就是在我们设定的时间间隔内如果没有得到一个值则发射一个错误。我们可以认为timeout()为一个Observable的限时的副本。如果在指定的时间间隔内Observable不发射值的话,它监听的原始的Observable时就会触发onError()函数。

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

Debounce

debounce()函数过滤掉由Observable发射的速率过快的数据;如果在一个指定的时间间隔过去了仍旧没有发射一个,那么它将发射最后的那个。
就像sample()和timeout()函数一样,debounce()使用TimeUnit对象指定时间间隔。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,406评论 6 503
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,732评论 3 393
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,711评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,380评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,432评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,301评论 1 301
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,145评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,008评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,443评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,649评论 3 334
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,795评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,501评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,119评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,731评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,865评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,899评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,724评论 2 354

推荐阅读更多精彩内容