2017-08-11 | Android android, reactive-streams, rxjava
忙了一段时间后赶紧趁着空闲时间填一下坑,文章其实写了一段时间但是没有发布,最近校对下确保没有错误发出来。本期将介绍下RxJava的变换操作符,也是最后一期常用操作符的介绍。
基本的转换操作符,可以把每一个元素转换成新的元素发射,接收一个Function<T,R>
作为转换逻辑的操作,下面是例子:
Flowable.just(1, 2, 3)
.map(integer -> "int" + integer)
.subscribe(ele -> Log.i("tag", String.valueOf(ele)));
上述例子中map操作符返回了Flowable<String>
,最终输出的结果为:int1、int2、int3。
上面的Map操作符是把每一个元素转换成一个新的元素,但是flatMap操作符是把每一个元素转换成新的被观察者,每个被观察者发射的元素将会合并成新的被观察者,这些元素顺序输出,例如下面的:
Flowable.just(1, 2, 3)
.flatMap((Function<Integer, Publisher<?>>)
integer -> Flowable.just("a",integer))
.subscribe(ele -> Log.i("tag", String.valueOf(ele)));
上述代码中把每一个just发射的元素转换成新的Flowable,而每一个新的Flowable额外添加一个“a”元素,所以上述的例子输出结果是:a、1、a、2、a、3。
flatMapIterable与flatMap类似,但是flatMapIterable是把每一个元素转换成Iterable,例子如下:
Flowable.just(1, 2, 3)
.flatMapIterable((Function<Integer, Iterable<?>>)
integer -> Arrays.asList("a", integer))
.subscribe(ele -> Log.i("tag", String.valueOf(ele)));
上述代码把每一个元素转换成一个List,每个list以元素“a”开头,所以上述的例子输出结果是:a、1、a、2、a、3。
concatMap操作符合flatMap操作符类似,接收的参数和转换都是类似的,例子如下:
Flowable.just(1, 2, 3)
.concatMap(integer -> Flowable.just("a", integer))
.subscribe(ele -> Log.i("tag", String.valueOf(ele)));
上述的例子输出结果是:a、1、a、2、a、3。flatMap操作符内部是使用merge合并元素,concatMap操作符则是通过concat合并元素,前者可能会出现元素交错问题,后者严格按照顺序发射。另外concatMap也有类似的concatMapIterable操作符,这里就不一样介绍了。
switchMap用法与flatMap类似,但是转换出来的每一个新的数据(被观察者)发射会取代掉前一个被观察者,如下例子:
Flowable.just(1, 2, 3)
.switchMap(integer ->
Flowable.timer(1, TimeUnit.SECONDS)
.map(longValue -> integer)
)//延迟1s发送元素
.subscribe(ele -> Log.i("tag", String.valueOf(ele)));
上面的例子最终只会输出3这个元素,其他元素被覆盖替代掉不再发送。
强制转换每一个元素的类型,内部调用map操作符来进行转换:
Flowable.just(1, 2, 3)
.cast(Number.class)
.subscribe(ele -> Log.i("tag", String.valueOf(ele)));
上述代码把每个元素都转换成Number类型,然后再发射。
扫描每一个元素,第一个元素将忽略,从第二个元素开始(可以获得上一个元素的值)进行变换后返回,例如:
Flowable.just(1, 2, 3)
.scan((last, item) -> {
Log.i("tag", "last:" + String.valueOf(last));
Log.i("tag", "item:" + String.valueOf(item));
return item+1;
})
.subscribe(ele -> Log.i("tag", String.valueOf(ele)));
上述代码输出结果为1、3、4。
buffer操作符是把多个元素打包成一个元素一次过发送数据,例如下面例子:
Flowable.just(1, 2, 3, 4, 5)
.buffer(3)//三个元素打包成一个元素
.subscribe(intList -> Log.i("tag", intList.toString()));
上述代码把三个元素组合成一个List发送,输出结果为:[1, 2, 3]、[4, 5]。
把所有元素转换成一个List一次过发送出去,如下面例子:
Flowable.just(1, 2, 3, 4, 5)
.toList()
.subscribe(intList -> Log.i("tag", intList.toString()));
上述代码输出[1, 2, 3, 4, 5]。除了toList操作符以外,还有toSortedList操作符,而且toSortedList操作符也支持自定义排序方式,这里就不展开了。
groupBy操作符通过Function接收每个数据的分组key,然后返回GroupedFlowable,使用者可以再订阅这个被观察者进行数据输出,由于使用lambda表达式可能加大理解难度,这里给出普通写法的例子:
Flowable.just(1, 2, 3, 4, 5)
.groupBy(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
//这里的返回值是分组的key
return integer > 2 ? "A组" : "B组";
}
})
.subscribe(new Consumer<GroupedFlowable<String, Integer>>() {
@Override
public void accept(GroupedFlowable<String, Integer> groupedFlowable)
throws Exception {
//订阅转换成GroupedFlowable
groupedFlowable.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
String key = groupedFlowable.getKey();
Log.i("tag", key + ":" + String.valueOf(integer));
}
});
}
});
上述代码将输出:“B组:1、B组:2、A组:3、A组:4、A组:5”,上述代码转换成lambda表达式为:
Flowable.just(1, 2, 3, 4, 5)
.groupBy(integer -> integer > 2 ? "A组" : "B组")
.subscribe(groupedFlowable ->
groupedFlowable.subscribe(
integer -> Log.i("tag", groupedFlowable.getKey()
+ ":" + String.valueOf(integer))
));
熟悉了groupBy后,toMap也是类似的,可以通过自定义key、value转换成对应的map,如下例子:
Flowable.just(1, 2, 3, 4, 5)
.toMap(integer -> "key" + integer)//第一个参数Function返回Map的key
.subscribe(map -> Log.i("tag", map.toString()));
上述代码输出:“{key5=5, key2=2, key4=4, key1=1, key3=3}”,另外toMap还可以支持自定义每个item对应的value值(传入第二个Function处理),这里就不一一介绍了。
RxJava 2.x中基本常用的操作符到此也说得差不多了,虽然还有很多其他的操作符还没有解析,但是理解了这些,大部分场景都够用了,万变不离其宗,以后有不懂的操作符也可以自行学习了,系列文章接下来将介绍下RxJava处理错误的机制和Android上的应用。
RxJava 2.x 使用详解(一) 快速入门: https://maxwell-nc.github.io/android/rxjava2-1.html
RxJava 2.x 使用详解(二) 创建操作符: https://maxwell-nc.github.io/android/rxjava2-2.html
RxJava 2.x 使用详解(三) 过滤操作符: https://maxwell-nc.github.io/android/rxjava2-3.html
RxJava 2.x 使用详解(四) 合并聚合操作符: https://maxwell-nc.github.io/android/rxjava2-4.html
RxJava 2.x 使用详解(五) 条件操作符: https://maxwell-nc.github.io/android/rxjava2-5.html
RxJava 2.x 使用详解(六) 变换操作符: https://maxwell-nc.github.io/android/rxjava2-6.html
原创文章,欢迎转载,请保留出处。有任何错误、疑问或者建议,欢迎指出。
请注明文章出自于:https://maxwell-nc.github.io/android/rxjava2-6.html