转载请注明出处:https://zhuanlan.zhihu.com/p/21966621

  • 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>() {@Overridepublic Boolean call(Community community) {return community.houses.size()>10;}}).subscribe(new Action1<Community>() {@Overridepublic 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>() {@Overridepublic 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>() {@Overridepublic 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>() {@Overridepublic void onCompleted() {System.exit(0);}@Overridepublic void onError(Throwable e) {}@Overridepublic 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>() {@Overridepublic Boolean call(Integer integer) {return integer >= 5;}}).subscribe(new Action1<Integer>() {@Overridepublic 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>() {@Overridepublic 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>() {@Overridepublic 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>() {@Overridepublic String call(House house) {return house.communityName;}}).subscribe(new Action1<House>() {@Overridepublic 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>() {@Overridepublic void call(Integer i) {System.out.print(i + " ");}});

程序输出:


2 1 2 3 4 3 4 5

distinctUntilChanged(Func1)distinct(Func1)一样,根据Func1中call方法产生一个Key来判断两个相邻的数据项是否相同。

我们还是拿前面的过滤房源的例子:

Observable.from(houses).distinctUntilChanged(new Func1<House, String>() {@Overridepublic String call(House house) {return house.communityName;}}).subscribe(new Action1<House>() {@Overridepublic void call(House house) {System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc);}
});

程序输出:

小区:中粮·海景壹号; 房源描述:中粮海景壹号新出大平层!总价4500W起
小区:竹园新村; 房源描述:满五唯一,黄金地段
小区:中粮·海景壹号; 房源描述:毗邻汤臣一品
小区:竹园新村; 房源描述:顶层户型,两室一厅
小区:中粮·海景壹号; 房源描述:南北通透,豪华五房

First

first()顾名思义,它是的Observable只发送观测序列中的第一个数据项。

获取房源列表houses中的第一套房源:

Observable.from(houses).first().subscribe(new Action1<House>() {@Overridepublic void call(House house) {System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc);}                });

程序输出:

小区:中粮·海景壹号; 房源描述:中粮海景壹号新出大平层!总价4500W起

first(Func1)只发送符合条件的第一个数据项。

现在我们要获取房源列表houses中小区名为竹园新村的第一套房源。

Observable.from(houses).first(new Func1<House, Boolean>() {@Overridepublic Boolean call(House house) {return "竹园新村".equals(house.communityName);}}).subscribe(new Action1<House>() {@Overridepublic void call(House house) {System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc);}});

程序输出:

小区:竹园新村; 房源描述:满五唯一,黄金地段

Last

last()只发射观测序列中的最后一个数据项。

获取房源列表中的最后一套房源:

Observable.from(houses).last().subscribe(new Action1<House>() {@Overridepublic void call(House house) {System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc);}});

程序输出:

小区:中粮·海景壹号; 房源描述:南北通透,豪华五房

last(Func1)只发射观测序列中符合条件的最后一个数据项。

获取房源列表houses中小区名为竹园新村的最后一套房源:

Observable.from(houses).last(new Func1<House, Boolean>() {@Overridepublic Boolean call(House house) {return "竹园新村".equals(house.communityName);}}).subscribe(new Action1<House>() {@Overridepublic void call(House house) {System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc);}});

程序输出:

小区:竹园新村; 房源描述:顶层户型,两室一厅

这一章我们就先聊到这,更多的过滤类操作符的介绍大家可以去查阅官方文档和源码;在下一章我们将继续介绍组合类操作符。

如果大家喜欢这一系列的文章,欢迎关注我的知乎专栏和GitHub。

  • 知乎专栏:https://zhuanlan.zhihu.com/baron

  • GitHub:https://github.com/BaronZ88

RxJava系列四(过滤操作符)相关推荐

  1. RxJava系列4(过滤操作符)

    前面一篇文章中我们介绍了转换类操作符,那么这一章我们就来介绍下过滤类的操作符.顾名思义,这类operators主要用于对事件数据的筛选过滤,只返回满足我们条件的数据.过滤类操作符主要包含: Filte ...

  2. RxJava系列6(从微观角度解读RxJava源码)

    RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...

  3. RxJava系列7(最佳实践)

    RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...

  4. RxJava系列1(简介)

    RxJava系列1(简介) RxJava系列2(基本概念及使用介绍) RxJava系列3(转换操作符) RxJava系列4(过滤操作符) RxJava系列5(组合操作符) RxJava系列6(从微观角 ...

  5. RxJava从入门到不离不弃(四)——过滤操作符

    RxJava中的过滤操作符,顾名思义,这类操作符主要用于对事件数据的筛选过滤,只返回满足我们条件的数据. 我们试想一下这样的一个需求,有一个学生集合,要求将其中成绩不及格的学生过滤,返回成绩合格的学生 ...

  6. RxJava 过滤操作符(Filtering Observables Operators)

    RxJava系列教程: 1. RxJava使用介绍 [视频教程] 2. RxJava操作符   • Creating Observables(Observable的创建操作符) [视频教程]   • ...

  7. 解剖 RxJava 之过滤操作符

    介绍 此文章结合 Github AnalyseRxJava 项目,给 Android 开发者带来 RxJava 详细的解说.参考自 RxJava Essential 及书中的例子 关于 RxJava ...

  8. Carson带你学Android:RxJava过滤操作符

    前言 Rxjava由于其基于事件流的链式调用.逻辑简洁 & 使用简单的特点,深受各大 Android开发者的欢迎. 今天,我将为大家详细介绍RxJava操作符中最常用的 过滤操作符,希望你们会 ...

  9. android rxjava 过滤,解剖 RxJava 之过滤操作符

    介绍 此文章结合 Github AnalyseRxJava 项目,给 Android 开发者带来 RxJava 详细的解说.参考自 RxJava Essential 及书中的例子 关于 RxJava ...

最新文章

  1. jwttoken解码_使用 JSON WEB TOKEN (jwt) 验证
  2. 云炬随笔20210714(1)
  3. CSS3选择器(二)--表单
  4. deb 中标麒麟_「图」百度网盘Linux版放出deb包客户端:新增支持Ubuntu 18.04 LTS
  5. redhat9.0配置apache 出现乱码
  6. openRefine使用报告
  7. 图片格式 tif转jpg 用Matlab实现
  8. Java学习第一周总结
  9. CYUSB3014设计方案|替代CYUSB3014芯片|方寸微T630可完全替代兼容CYPRESS CYUSB3014
  10. 学会生命倒计时法,就是精彩生活的开始
  11. 浅谈git rebase和git checkout --ours(theirs)
  12. 程序员不要太过于看重编码技巧,相比而言思想更重要
  13. 2022-2028全球植物奶油行业调研及趋势分析报告
  14. python 实现凯撒密码 改良版 非常适合小白练手
  15. 玩转云端 | 网站安全监测,轻松拿捏全站安全态势
  16. oracle字符串函数
  17. 微信拉群服务器繁忙,微信群拉人有限制吗?解决方案是什么?
  18. 校园网开热点显示无Internet连接和360免费WiFi猎豹WiFi冲突解决办法
  19. 第一章中央银行制度的形成与发展
  20. 互联网金融P2P主业务场景自动化测试

热门文章

  1. webServer tomcat5/tomcat6/tomcat7诠释
  2. 学习腾讯的产品管理之道
  3. 旧金山漫记(四):夜困火车站
  4. 模拟消耗CPU之shell脚本
  5. 荧光透视的计算机辅助外科手术,「电信学」「2008.11」基于荧光透视的电磁跟踪骨科X射线导航实践研究...
  6. Redis集群在线分片
  7. 序列化技术的选型-技术层面
  8. Lambda表达式练习3【应用】
  9. RabbitMQ延时队列原理讲解
  10. SpringBoot整合RocketMQ之环境搭建以及Producer发送消息