过滤类操作符(fileter take takeLast takeUntil distinct distinctUntilChanged skip skipLast …)
Filter
filter(Func1)用来过滤观测序列中我们不想要的值,只返回满足条件的值,我们看下原理图:

1 2 3 4 5 6 7 8 9 10 11 12
| 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个元素.

1 2 3 4 5 6 7 8
| 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个元素。

1 2 3 4 5 6 7 8
| 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并终止。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| 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方法来判断是否需要终止发射数据。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 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个小区
1 2 3 4 5 6 7 8
| 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发射的速率过快的数据;如果在一个指定的时间间隔过去了仍旧没有发射一个,那么它将发射最后的那个。通常我们用来结合RxBinding(Jake Wharton大神使用RxJava封装的Android UI组件)使用,防止button重复点击。

debounce(Func1)可以根据Func1的call方法中的函数来过滤,Func1中的中的call方法返回了一个临时的Observable,如果原始的Observable在发射一个新的数据时,上一个数据根据Func1的call方法生成的临时Observable还没结束,那么上一个数据就会被过滤掉。

Distinct
distinct()的过滤规则是只允许还没有发射过的数据通过,所有重复的数据项都只会发射一次。

过滤掉一段数字中的重复项:
1 2 3 4 5 6 7 8 9 10
| 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()一样过滤掉重复的数据项。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| 假设我们要过滤掉一堆房源中小区名重复的小区: List<House> houses = new ArrayList<>(); 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发射的当前数据项和前一个数据项是否相同。

1 2 3 4 5 6 7 8 9 10
| 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来判断两个相邻的数据项是否相同。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| 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
first()顾名思义,它是的Observable只发送观测序列中的第一个数据项。

1 2 3 4 5 6 7 8 9 10 11
| 获取房源列表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)只发送符合条件的第一个数据项。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| 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()只发射观测序列中的最后一个数据项。

1 2 3 4 5 6 7 8 9 10 11
| Observable.from(houses) .last() .subscribe(new Action1<House>() { @Override public void call(House house) { System.out.println("小区:" + house.communityName + "; 房源描述:" + house.desc); } }); 小区:中粮·海景壹号; 房源描述:南北通透,豪华五房
|