RxJava系列4(过滤操作符)
- RxJava系列1(简介)
- RxJava系列2(基本概念及使用介绍)
- RxJava系列3(转换操作符)
- RxJava系列4(过滤操作符)
- RxJava系列5(组合操作符)
- RxJava系列6(从微观角度解读RxJava源码)
- RxJava系列7(最佳实践)
前面一篇文章中我们介绍了转换类操作符,那么这一章我们就来介绍下过滤类的操作符。顾名思义,这类operators主要用于对事件数据的筛选过滤,只返回满足我们条件的数据。过滤类操作符主要包含: Filter
Take
TakeLast
TakeUntil
Skip
SkipLast
ElementAt
Debounce
Distinct
DistinctUntilChanged
First
Last
等等。
Filter
filter(Func1)
用来过滤观测序列中我们不想要的值,只返回满足条件的值,我们看下原理图:
还是拿前面文章中的小区Community[] communities
来举例,假设我需要赛选出所有房源数大于10个的小区,我们可以这样实现:
Observable.from(communities)
.filter(new Func1<Community, Boolean>() {
@Override
public Boolean call(Community community) {
return community.houses.size()>10;
}
}).subscribe(new Action1<Community>() {
@Override
public void call(Community community) {
System.out.println(community.name);
}
});
Take
take(int)
用一个整数n作为一个参数,从原始的序列中发射前n个元素.
现在我们需要取小区列表communities
中的前10个小区
Observable.from(communities)
.take(10)
.subscribe(new Action1<Community>() {
@Override
public void call(Community community) {
System.out.println(community.name);
}
});
TakeLast
takeLast(int)
同样用一个整数n作为参数,只不过它发射的是观测序列中后n个元素。
获取小区列表communities
中的后3个小区
Observable.from(communities)
.takeLast(3)
.subscribe(new Action1<Community>() {
@Override
public void call(Community community) {
System.out.println(community.name);
}
});
TakeUntil
takeUntil(Observable)
订阅并开始发射原始Observable,同时监视我们提供的第二个Observable。如果第二个Observable发射了一项数据或者发射了一个终止通知,takeUntil()
返回的Observable会停止发射原始Observable并终止。
Observable<Long> observableA = Observable.interval(300, TimeUnit.MILLISECONDS);
Observable<Long> observableB = Observable.interval(800, TimeUnit.MILLISECONDS);
observableA.takeUntil(observableB)
.subscribe(new Subscriber<Long>() {
@Override
public void onCompleted() {
System.exit(0);
}
@Override
public void onError(Throwable e) {
}
@Override
public void onNext(Long aLong) {
System.out.println(aLong);
}
});
try {
Thread.sleep(Integer.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
程序输出:
0
1
takeUntil(Func1)
通过Func1中的call方法来判断是否需要终止发射数据。
Observable.just(1, 2, 3, 4, 5, 6, 7)
.takeUntil(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer >= 5;
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println(integer);
}
});
程序输出:
1
2
3
4
5
Skip
skip(int)
让我们可以忽略Observable发射的前n项数据。
过滤掉小区列表communities
中的前5个小区
Observable.from(communities)
.skip(5)
.subscribe(new Action1<Community>() {
@Override
public void call(Community community) {
System.out.println(community.name);
}
});
SkipLast
skipLast(int)
忽略Observable发射的后n项数据。
ElementAt
elementAt(int)
用来获取元素Observable发射的事件序列中的第n项数据,并当做唯一的数据发射出去。
Debounce
debounce(long, TimeUnit)
过滤掉了由Observable发射的速率过快的数据;如果在一个指定的时间间隔过去了仍旧没有发射一个,那么它将发射最后的那个。通常我们用来结合RxBing(Jake Wharton大神使用RxJava封装的Android UI组件)使用,防止button重复点击。
debounce(Func1)
可以根据Func1的call方法中的函数来过滤,Func1中的中的call方法返回了一个临时的Observable,如果原始的Observable在发射一个新的数据时,上一个数据根据Func1的call方法生成的临时Observable还没结束,那么上一个数据就会被过滤掉。
Distinct
distinct()
的过滤规则是只允许还没有发射过的数据通过,所有重复的数据项都只会发射一次。
过滤掉一段数字中的重复项:
Observable.just(2, 1, 2, 2, 3, 4, 3, 4, 5, 5)
.distinct()
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer i) {
System.out.print(i + " ");
}
});
程序输出:
2 1 3 4 5
distinct(Func1)
参数中的Func1中的call方法会根据Observable发射的值生成一个Key,然后比较这个key来判断两个数据是不是相同;如果判定为重复则会和distinct()
一样过滤掉重复的数据项。
假设我们要过滤掉一堆房源中小区名重复的小区:
List<House> houses = new ArrayList<>();
//House构造函数中的第一个参数为该房源所属小区名,第二个参数为房源描述
List<House> houses = new ArrayList<>();
houses.add(new House("中粮·海景壹号", "中粮海景壹号新出大平层!总价4500W起"));
houses.add(new House("竹园新村", "满五唯一,黄金地段"));
houses.add(new House("竹园新村", "一楼自带小花园"));
houses.add(new House("中粮·海景壹号", "毗邻汤臣一品"));
houses.add(new House("中粮·海景壹号", "顶级住宅,给您总统般尊贵体验"));
houses.add(new House("竹园新村", "顶层户型,两室一厅"));
houses.add(new House("中粮·海景壹号", "南北通透,豪华五房"));
Observable.from(houses)
.distinct(new Func1<House, String>() {
@Override
public String call(House house) {
return house.communityName;
}
}).subscribe(new Action1<House>() {
@Override
public void call(House house) {
System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc);
}
});
程序输出:
小区:中粮·海景壹号; 房源描述:中粮海景壹号新出大平层!总价4500W起
小区:竹园新村; 房源描述:满五唯一,黄金地段
DistinctUntilChanged
distinctUntilChanged()
和distinct()
类似,只不过它判定的是Observable发射的当前数据项和前一个数据项是否相同。
同样还是上面过滤数字的例子:
Observable.just(2, 1, 2, 2, 3, 4, 3, 4, 5, 5)
.distinctUntilChanged()
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer i) {
System.out.print(i + " ");
}
});
程序输出:
2 1 2 3 4 3 4 5
distinctUntilChanged(Func1)
和distinct(Func1)
一样,根据Func1中call方法产生一个Key来判断两个相邻的数据项是否相同。
我们还是拿前面的http://ocjtywvav.bkt.clouddn.com/rxjava/operator/filter/过滤房源的例子:
Observable.from(houses)
.distinctUntilChanged(new Func1<House, String>() {
@Override
public String call(House house) {
return house.communityName;
}
}).subscribe(new Action1<House>() {
@Override
public void call(House house) {
System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc);
}
});
程序输出:
小区:中粮·海景壹号; 房源描述:中粮海景壹号新出大平层!总价4500W起
小区:竹园新村; 房源描述:满五唯一,黄金地段
小区:中粮·海景壹号; 房源描述:毗邻汤臣一品
小区:竹园新村; 房源描述:顶层户型,两室一厅
小区:中粮·海景壹号; 房源描述:南北通透,豪华五房
First
first()
顾名思义,它是的Observable只发送观测序列中的第一个数据项。
获取房源列表houses
中的第一套房源:
Observable.from(houses)
.first()
.subscribe(new Action1<House>() {
@Override
public void call(House house) {
System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc);
}
});
程序输出:
小区:中粮·海景壹号; 房源描述:中粮海景壹号新出大平层!总价4500W起
first(Func1)
只发送符合条件的第一个数据项。
现在我们要获取房源列表houses
中小区名为竹园新村的第一套房源。
Observable.from(houses)
.first(new Func1<House, Boolean>() {
@Override
public Boolean call(House house) {
return "竹园新村".equals(house.communityName);
}
})
.subscribe(new Action1<House>() {
@Override
public void call(House house) {
System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc);
}
});
程序输出:
小区:竹园新村; 房源描述:满五唯一,黄金地段
Last
last()
只发射观测序列中的最后一个数据项。
获取房源列表中的最后一套房源:
Observable.from(houses)
.last()
.subscribe(new Action1<House>() {
@Override
public void call(House house) {
System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc);
}
});
程序输出:
小区:中粮·海景壹号; 房源描述:南北通透,豪华五房
last(Func1)
只发射观测序列中符合条件的最后一个数据项。
获取房源列表houses
中小区名为竹园新村的最后一套房源:
Observable.from(houses)
.last(new Func1<House, Boolean>() {
@Override
public Boolean call(House house) {
return "竹园新村".equals(house.communityName);
}
})
.subscribe(new Action1<House>() {
@Override
public void call(House house) {
System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc);
}
});
程序输出:
小区:竹园新村; 房源描述:顶层户型,两室一厅
这一章我们就先聊到这,更多的过滤类操作符的介绍大家可以去查阅官方文档和源码;在下一章我们将继续介绍组合类操作符。
如果你喜欢我的文章,就关注下我的知乎专栏或者在 GitHub 上添个 Star 吧!
RxJava系列4(过滤操作符)的更多相关文章
- RxJava系列5(组合操作符)
RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...
- RxJava系列3(转换操作符)
RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...
- RxJava系列番外篇:一个RxJava解决复杂业务逻辑的案例
之前写过一系列RxJava的文章,也承诺过会尽快有RxJava2的介绍.无奈实际项目中还未真正的使用RxJava2,不敢妄动笔墨.所以这次还是给大家分享一个使用RxJava1解决问题的案例,希望对大家 ...
- RxJava系列7(最佳实践)
RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...
- RxJava系列6(从微观角度解读RxJava源码)
RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...
- RxJava系列2(基本概念及使用介绍)
RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...
- RxJava系列1(简介)
RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...
- RxJava系列之二 变换类操作符具体解释1
1.回想 上一篇文章我们主要介绍了RxJava , RxJava 的Observables和 RxJava的just操作符.以及RxJava一些经常使用的操作. 没看过的抓紧点我去看吧. 事实上RxJ ...
- RxJava2实战---第五章 变换操作符和过滤操作符
RxJava2实战---第五章 变换操作符和过滤操作符 RxJava的变换操作符主要包括以下几种: map():对序列的每一项都用一个函数来变换Observable发射的数据序列. flatMap() ...
随机推荐
- 微信公众号开发 VS2015本地调试
1.部署一个微信公众号服务在本地IIS: 2.下载一个ngrok 穿网工具,放到部署文件夹根目录: ngrok穿网 在部署路径下打开cmd,输入 ngrok http [端口号] 4.将映射的URL ...
- sort命令与cat区别25.1 由于sort默认是把结果输出到标准输出,所以需要用重定向才能将结果写入文件,形如sort filename > newfile [root@shiyan a]# cat a.txt aaaaaa [root@shiyan a]# sort a.txt >c.txt ------------- 在重定向前会自动创建c.txt这个文件。 [root@shiyan
25.1 由于sort默认是把结果按照行排序后输出到标准输出,所以需要用重定向才能将结果写入文件,形如sort filename > newfile[root@shiyan a]# cat a. ...
- python作业03-文件操作&函数
一.文件处理相关 1.编码问题 (1)请说明python2 与python3中的默认编码是什么?答:Python2默认的字符编码是ASCII,默认的文件编码也是ASCII :python3默认的字符编 ...
- js实现单双行文本溢出添加省略号
# 单双行文本溢出省略 ``` // 2. 当内容过多的时候,单行省略号: overflow: hidden; text-overflow:ellipsis; white-space: nowrap; ...
- 云计算 --> 三种服务模式IaaS,PaaS,SaaS
三种服务模式IaaS,PaaS,SaaS “云”其实是互联网的一个隐喻,“云计算”其实就是使用互联网来接入存储或者运行在远程服务器端的应用,数据,或者服务.任何一个使用基于互联网的方法来计算,存储和开 ...
- WEB烟花效果——Canvas实现
摘要 本文主要介绍一种WEB形式的烟花(fireworks)效果(图1所示),该效果基于Canvas实现,巧妙地运用了canvas绘图的特性,并加入了物理力作用的模拟,使整体效果非常绚丽 ...
- Linux下的进程与线程(一)—— 进程概览
进程是操作系统分配资源的基本单位.线程是操作系统进行运行和调度的基本单位. 进程之间可以切换,以便轮流占用CPU,实现并发.一般进程运行在用户模式下,只能执行指令集中的部分指令. 当进程进行上下文切换 ...
- apache学习教程
5.apache教程 httpd.conf文件分析 ServerRoot "E:/phpwebenv/PHPTutorial/Apache" #apache软件安装的位置 List ...
- alpha冲刺第五天
一.合照 二.项目燃尽图 三.项目进展 调整了一些界面的布局 细化了部分小功能的界面 注册界面和服务器响应了,但是在insert数据库方面出现了错误 四.明日规划 继续研究如何将注册的内容插入数据库 ...
- servlet线程同步问题-代码实现同步(转)
从servlet的生命周期中,我们知道,当第一次访问某个servlet后,该servlet的实例就会常驻 内存,以后再次访问该servlet就会访问同一个servlet实例,这样就带来多个用户去访问一 ...