一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第3天,点击查看活动详情。
过滤操作符
过滤操作符用于过滤和选择Observable发射的数据序列。
1.filter
filter操作符是对源Observable产生的结果自定义规则进行过滤,只有满足条件的才会提交给订阅者,我们用它可以轻松实现对null数据的过滤。
Observable.range(0,20).filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) throws Exception {
return integer%5==0;
}
}).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i("TAG", "accept: "+integer);
}
});
输出结果
I/TAG: accept: 0
I/TAG: accept: 5
I/TAG: accept: 10
I/TAG: accept: 15
2.elementAt
elementAt操作符用于返回指定位置的数据,其重载方法elementAt(long index, T defaultItem)可指定默认值。
Observable.range(0, 5).elementAt(10, -1).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer);
}
});
Observable.range(0, 5).elementAt(2).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: " + integer);
}
});
输出结果为
I/TAG: accept: -1
I/TAG: accept: 2
3.distinct
distinct操作符可用于过滤重复元素,其重载方法distinct(Function<? super T, K> keySelector)可以指定重复规则
User user1 = new User("张三丰",100);
User user2 = new User("张翠山",30);
User user3 = new User("张无极",18);
User user4 = new User("珠儿",15);
User user5 = new User("周芷若",16);
User user6 = new User("小昭",15);
User user7 = new User("白眉鹰王",100);
User user8 = new User("白眉鹰王",101);
User user9 = new User("白眉鹰王",102);
User user10 = new User("白眉鹰王",103);
Observable.just(user1,user2,user3,user4,user5,user6,user7,user8,user9,user10)
.distinct()
.subscribe(new Consumer<User>() {
@Override
public void accept(User user) throws Exception {
Log.i(TAG, "accept: "+user);
}
});
Log.i(TAG, "============distinct()============");
Observable.just(user1,user2,user3,user4,user5,user6,user7,user8,user9,user10)
.distinct(new Function<User, Integer>() {
@Override
public Integer apply(User user) throws Exception {
return user.getAge();//指定age相同则视为重复
}
}).subscribe(new Consumer<User>() {
@Override
public void accept(User user) throws Exception {
Log.i(TAG, "accept: "+user.toString());
}
});
输出结果
I/TAG: accept: 张三丰 100岁
I/TAG: accept: 张翠山 30岁
I/TAG: accept: 张无极 18岁
I/TAG: accept: 珠儿 15岁
I/TAG: accept: 周芷若 16岁
I/TAG: accept: 小昭 15岁
I/TAG: accept: 白眉鹰王 100岁
I/TAG: accept: 白眉鹰王 101岁
I/TAG: accept: 白眉鹰王 102岁
I/TAG: accept: 白眉鹰王 103岁
I/TAG: ============distinct()============
I/TAG: accept: 张三丰 100岁
I/TAG: accept: 张翠山 30岁
I/TAG: accept: 张无极 18岁
I/TAG: accept: 珠儿 15岁
I/TAG: accept: 周芷若 16岁
I/TAG: accept: 白眉鹰王 101岁
I/TAG: accept: 白眉鹰王 102岁
I/TAG: accept: 白眉鹰王 103岁
4.take/takeLast
take操作符只取Observable发射的前几项,takeLast与之相反。
Observable.range(0, 6).take(3).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: "+integer);
}
});
输出结果
I/TAG: accept: 0
I/TAG: accept: 1
I/TAG: accept: 2
5.skip
skip操作符会过滤掉Observable发射的前几项,skipLast与之相反。
skip可以接受一个时长参数。它会丢弃原始Observable开始的那段时间发射的数据,时长和时间单位通过参数指定。
Observable.range(0, 6).skip(3).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: "+integer);
}
});
输出结果
I/TAG: accept: 3
I/TAG: accept: 4
I/TAG: accept: 5
组合操作符可以将多个Observable转换成我们想要的Observable。
组合操作符
1.startWith/startWithArray
startWith(startWithArray)操作符可以在源Observable发射的数据开头插上一些数据

Observable.just(3,4,5)
.startWithArray(0,1,2)//在3,4,5前边插入0,1,2
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: "+integer);
}
});
输出结果如下
I/TAG: accept: 0
I/TAG: accept: 1
I/TAG: accept: 2
I/TAG: accept: 3
I/TAG: accept: 4
I/TAG: accept: 5
2.merge
merge操作符可以将多个Observable的输出合并在一个Observable中进行发射,merge可能会让发射的数据错乱。注意源Observable中任何一个发射的onError都会立即传递给观察者,而且会终止合并后的Observable。

Observable obs1 = Observable.just(1,2,3).subscribeOn(Schedulers.io());
Observable obs2 = Observable.just(4,5,6);
Observable.merge(obs1,obs2).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: "+integer);
}
});
输出结果如下
I/TAG: accept: 4
I/TAG: accept: 5
I/TAG: accept: 6
I/TAG: accept: 1
I/TAG: accept: 2
I/TAG: accept: 3
3.concat
concat操作符与merge操错符类似,不过contact操作符严格按照顺序发射数据,前面的Observable没有发射完,是不会发射后面的数据的。

Observable obs1 = Observable.just(1,2,3).subscribeOn(Schedulers.io());
Observable obs2 = Observable.just(4,5,6);
Observable.concat(obs1,obs2).subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
Log.i(TAG, "accept: "+integer);
}
});
输出结果如下
I/TAG: accept: 1
I/TAG: accept: 2
I/TAG: accept: 3
I/TAG: accept: 4
I/TAG: accept: 5
I/TAG: accept: 6
4.zip
zip操作符可以将两个或者多个Observable发射的数据按顺序组合起来,然后根据指定的函数变换他们,并发射一个新值,每个数据都只能用一次。zip只发射与发射数据项最少的Observable一样多的数据。
Observable obs1 = Observable.just(1,2,3,4).subscribeOn(Schedulers.io());
Observable obs2 = Observable.just("a","b","c");
Observable.zip(obs1, obs2, new BiFunction<Integer,String,String>() {
@Override
public String apply(Integer integer, String s) throws Exception {
return integer+s;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String o) throws Exception {
Log.i(TAG, "accept: "+o);
}
});
输出结果如下
I/TAG: accept: 1a
I/TAG: accept: 2b
I/TAG: accept: 3c
obs1发射了4个数据项,obs2发射了3个数据项,结果只输出了3个,所以zip最终组合的数据的数量由发射数据最少的Observable来决定。
5.combineLatest
combineLatest操作符与zip类似,只不过zip是当原始Observable都发射了数据才组合他们并发射,儿combineLatest是当原始Observable中任意一个发射了数据就开始组合他们最近发射的数据,然后发射这个组合值,所以使用combineLatest的前提是所有的Observable都发射过数据。

Observable obs1 = Observable.interval(1000, TimeUnit.MILLISECONDS);
Observable obs2 = Observable.interval(600, TimeUnit.MILLISECONDS);
Observable.combineLatest(obs1, obs2, new BiFunction<Long,Long,String>() {
@Override
public String apply(Long aLong, Long aLong2) throws Exception {
return aLong+" "+aLong2;
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.i(TAG, "accept: "+s);
}
});
输出结果如下
I/TAG: accept: 0 0
I/TAG: accept: 0 1
I/TAG: accept: 1 2
I/TAG: accept: 1 3
I/TAG: accept: 2 3
I/TAG: accept: 2 4