一、RxJava操作符概述
RxJava中的操作符就是为了提供函数式的特性,函数式最大的好处就是使得数据处理简洁易懂。
操作符实质上就是RxJava函数式编程模式的体现,在上篇文章中,我详细阐述了RxJava中观察者模式、Iterator模式、函数式编程模式概念的解读,详情请戳→文章传送门。
Rxjava操作符的类型众多,在本文中,我详细解释如图1.1所示的9种操作符。
图1.1 RxJava操作符的分类
本项目案例代码已上传Github,详情戳→GitHub案例代码。
图1.2 RxJava操作符案例图
二、RxJava操作符详解
1、创建操作符
创建操作符的分类如下图所示,关于create操作符的详细操作可在我的上篇文章中查看,在本文中不加以赘述,文章链接戳→文章传送门。在本文中从from操作符开始介绍。
图2.1 创建操作符的分类
注:在这里,我将请求的不完整回调在父类中进行了封装,具体代码可查看GitHub的代码链接。
①from操作符
在这里以发送数组为例,from操作符的使用代码如下所示:
//from操作符,创建以数组内容发送事件的ObservableString[] observableArr =newString[]{"Alex","Payne"};//onNextAction、onErrorAction提取到父类中,具体代码可查看GitHub的代码链接Observable.from(observableArr).subscribe(onNextAction, onErrorAction);
首先,我们查看如下所示from操作符的结构图,可以看到它有多种实现方式,但是有一个共同点,都会返回一个Observable对象。
图2.1.1 from操作符操作结构图
实质上,Observable将数组中的元素逐个进行发送,在发送过程中转换为Observable对象。
进一步查看源码,可得知from操作符的作用:将一个Iterable、一个Future、 或者一个数组,内部通过代理的方式转换成一个Observable。
Future转换为OnSubscribe是通过OnSubscribeToObservableFuture进行的,Iterable转换通过OnSubscribeFromIterable进行。数组通过OnSubscribeFromArray转换。
②just操作符
使用代码如下所示:
//just操作符,创建将逐个内容进行发送的Observable,其内部发送内容在内部以from的操作符的方式进行转换Observable.just("Alex","Payne").subscribe(onNextAction);
图2.1.2 just操作符结构图
查看just操作符的结构图,结合源码得知,just操作符将单个参数发送的内容通过ScalarSynchronousObservable转换为一个新的Observable对象,而将多个参数发送的内容转换为一个数组,然后将数组通过from操作符进行发送。
③interval操作符
interval操作符使用代码如下所示:
//interval操作符,创建以1秒为事件间隔发送整数序列的ObservableObservable.interval(1, TimeUnit.SECONDS, AndroidSchedulers.mainThread()).subscribe(onNextAction);
图2.1.3 interval操作符结构图
查看interval的结构图,其只能发送Long类型的数,实质上其作用为:创建一个按固定时间间隔发射整数序列的Observable,这个序列为一个无限递增的整数序列。
需要注意的是:interval默认在computation调度器上执行。你也可以传递一个可选的Scheduler参数来指定调度器。
④range操作符
range操作符使用的代码如下所示:
//range操作符,创建以发送范围内的整数序列的ObservableObservable.range(0,3).subscribe(onNextAction);
range操作符发射一个范围内的有序整数序列,并且我们可以指定范围的起始和长度
图2.1.4 range操作符参数释义
⑤repeat操作符
repeat操作符使用的代码如下所示:
//repeat操作符,创建一个以N次重复发送数据的ObservableObservable.range(0,3).repeat(2).subscribe(onNextAction);
在这里需要强调一下,它不是创建一个Observable,而是重复发射原始Observable的数据序列,这个序列或者是无限的,或者通过repeat(n)指定重复次数。
2、变换操作符
在这里我介绍如下图所示7种变换操作符,变换操作符的作用是将源Observable发送的数据进行变换。
图2.1 变换操作符的分类
①map操作符
map操作符使用的代码如下所示:
//map操作符,通过指定一个Func,将Observable转换为另一个Observable对象并发送Observable.just("Alex_Payne") .map(newFunc1() { @Override publicStringcall(Strings) {return"My Name is"+ s; } }).subscribe(onNextAction);
map操作符将源Observable发送的数据转换为一个新的Observable对象。
在这里,Func1和Action的区别在于,Func1包装的是有返回值的方法。另外,和ActionX 一样,FuncX 也有多个,用于不同参数个数的方法。
FuncX 和 ActionX 的区别在 FuncX 包装的是有返回值的方法。
②flatMap操作符
flatMap操作符使用的代码如下所示:
//flatMap操作符,将Observable发送的数据集合转换为Observable集合//flatMap的合并运行允许交叉,允许交错的发送事件String[] observableArr = {"Alex","Max","Bruce","Frank","Tom"}; Observable.from(observableArr).flatMap(newFunc1>() { @Override public Observable call(Strings) {returnObservable.just("My Name is:"+ s); } }).subscribe(onNextAction);
源Observable通过flatMap操作符转换为包含源Observable发送的所有子条目的Observable集合,可见下图的示意图,然后从Observable集合中逐个取出转化为单个Observable对象进行发送。不同于map操作符的一点就是一对多的转化。
图2.2.2 flatMap转换示意图
它的应用场景可以体现在源Observable发送的内容为一个复杂的数据集,例如一个Bean对象,而该外层Bean对象中一个成员变量为另一个内层Bean对象,我们想要拆解外层Bean对象获取内层Bean对象,就可以用flatMap操作符。
注意:FlatMap对这些Observables发射的数据做的是合并(merge)操作,因此它们可能是交错的。
③concatMap操作符
concatMap操作符使用的代码如下所示:
//concatMap操作符,将Observable发送的数据集合转换为Observable集合//解决了flatMap的交叉问题,将发送的数据连接发送String[] observableArr = {"Alex","Max","Bruce","Frank","Tom"}; Observable.from(observableArr).concatMap(newFunc1>() { @Override public Observable call(Strings) {returnObservable.just("My Name is:"+ s); } }).subscribe(onNextAction);
concatMap操作符类似于flatMap操作符,不同的一点是它按次序连接。
④cast操作符
cast操作符使用的代码如下所示:
//cast操作符,将类对象进行转换Object[] objectsArr = {"1","2","3"}; Observable.from(objectsArr).cast(String.class).subscribe(onNextAction);
cast操作符将源Observable发送的数据都强制转换为一个指定的类型,然后再发射数据。
需强调的一点是只能由父类对象转换为子类对象,否则会报错。
⑤flatMapIterable操作符
flatMapIterable操作符使用的代码如下所示:
//将数据集合转换为Iterable,在Iterable中对数据进行处理Observable.just(1,2,3).flatMapIterable(newFunc1>() {@OverridepublicIterablecall(Integer number){ ArrayList mList =newArrayList<>(); mList.add(1000+ number);returnmList; } }).subscribe(onNextAction);
flatMapIterable相当于是flatMap的变体,直接在内部以Iterable接口将集合数据进行接收,示意图如下所示:
图2.2.5 flatMapIterable示意图
⑥buffer操作符
buffer操作符使用的代码如下所示:
//buffer操作符,将原有Observable转换为一个新的Observable,这个新的Observable每次发送一组值,而不是一个个进行发送Observable.just(1,2,3,4,5,6) .buffer(3).subscribe(newAction1>() {@Overridepublicvoidcall(List mList){for(Integer i : mList) { Toast.makeText(getActivity(),"new Number i is:"+ i, Toast.LENGTH_SHORT).show(); } Toast.makeText(getActivity(),"Another request is called", Toast.LENGTH_SHORT).show(); } });
buffer操作符将原有Observable转换为一个新的Observable,这个新的Observable每次发送一组值,而不是一个个进行发送,我们可以定义这个新的Observable存放几个原有的Observable对象。
图2.2.6 buffer操作符示意图
⑦groupBy操作符
groupBy操作符使用的代码如下所示:
//groupBy操作符,可以做分组操作Observable.range(0,10).groupBy(newFunc1() {@OverridepublicIntegercall(Integer num){returnnum %3; } }).subscribe(newAction1>() {@Overridepublicvoidcall(finalGroupedObservable groupedObservable){ groupedObservable.subscribe(newAction1() {@Overridepublicvoidcall(Integer num){ Toast.makeText(getActivity(),"当前的组别是:"+ groupedObservable.getKey() +"组别内的数字是:"+ num, Toast.LENGTH_SHORT).show(); } }); } });
groupBy操作符,将原有的Observable对象转换为发送一组Observable集合的GroupedObservable对象,可以做分组操作,GroupedObservable将分组完毕的Observable对象可以继续发送。
注意:groupBy将原始Observable分解为一个发射多个GroupedObservable的Observable,一旦有订阅,每个GroupedObservable就开始缓存数据。因此,如果你忽略这些GroupedObservable中的任何一个,这个缓存可能形成一个潜在的内存泄露。因此,如果你不想观察,也不要忽略GroupedObservable。你应该使用像take(0)这样会丢弃自己的缓存的操作符。
3、过滤操作符
过滤操作符用于从Observable发射的数据中进行选择,在这里介绍如下图所示的8种。
图3.1 过滤操作符的分类
①filter操作符
filter操作符使用的代码如下所示:
//filter过滤操作符,对Observable发送的内容根据自定义的规则进行过滤Observable.range(0,5).filter(newFunc1() {@OverridepublicBooleancall(Integer num){returnnum >2;//自定义的条件,只有符合条件的结果才会提交给观察者} }).subscribe(onNextAction);
filter默认不在任何特定的调度器上执行。
②elementAt操作符
elementAt操作符使用的代码如下所示:
//elementAt操作符,用于返回指定位置后一位的数据,即脚标+1的数据//在这里发送0、1、2、3、4,脚标为3的数据为2,发送其后一位数据3Observable.range(0,5).elementAt(3).subscribe(onNextAction);
elementAt操作符获取原始Observable发射的数据序列指定索引位置的数据项,然后当做自己的唯一数据发射。对应示意图如下:
图2.3.2 elementAt操作符示意图
③distinct操作符
distinct操作符使用的代码如下所示:
//distinct操作符,用于Observable发送的元素的去重Observable.just(1,1,2,2,2,3).distinct().subscribe(onNextAction);
在这里需要强调一点:distinct操作符只允许还没有发射过的数据项通过。
④skip操作符
skip操作符使用的代码如下所示:
//skip操作符,用于Observable发送的元素前N项去除掉Observable.range(0,5).skip(2).subscribe(onNextAction);
skip操作符抑制Observable发射的前N项数据,只发送后N项数据
图2.3.4 skip操作符示意图
⑤take操作符
//take操作符,用于Observable发送的元素只取前N项Observable.range(0,5).take(2).subscribe(onNextAction);
图2.3.5 take操作符示意图
⑥ignoreElements操作符
//ignoreElements操作符,忽略掉源Observable发送的结果,只把Observable的onCompleted或onError发送Observable.range(0,5).ignoreElements().subscribe(onNextAction, onErrorAction, onCompletedAction);
IgnoreElements操作符抑制原始Observable发射的所有数据,只允许它的终止通知(onError或onCompleted)进行发送。
⑦throttleFirst操作符
//throttleFirst操作符,会定期发送这个时间段里源Observable发送的第一个数据//throttleFirst操作符默认在computaioin调度器上执行,其他的数据都会被过滤掉Observable.create(newObservable.OnSubscribe() {@Overridepublicvoidcall(Subscriber subscriber){for(inti =0; i <10; i++) { subscriber.onNext(i);//线程休眠100毫秒try{ Thread.sleep(100); }catch(InterruptedException e) { e.printStackTrace(); } } } }) .throttleFirst(200, TimeUnit.MILLISECONDS) .subscribe(onNextAction);
throttleFirst操作符会按照固定的时间间隔将信息进行发送。在这里我设置的事件间隔为200毫秒,其中每发送一个数据线程休眠100毫秒,所以最后会显示的数据为0,示意图如下:
图2..3.7 throttleFirst操作符示意图
注:throttleFirst操作符默认在computation调度器上执行,但是你可以使用第三个参数指定其它的调度器。
⑧throttleWithTimeOut操作符
//throttleWithTimeout操作符//源发射数据时,如果两次数据的发射间隔小于指定时间,就会丢弃前一次的数据,直到指定时间内都没有新数据发射时才进行发射 Observable.create(newObservable.OnSubscribe() {@Overridepublicvoidcall(Subscriber subscriber){ subscriber.onNext(1);try{ Thread.sleep(500); }catch(InterruptedException e) {throwExceptions.propagate(e); } subscriber.onNext(2);try{ Thread.sleep(500); }catch(InterruptedException e) {throwExceptions.propagate(e); } subscriber.onNext(3);try{ Thread.sleep(1000); }catch(InterruptedException e) {throwExceptions.propagate(e); } subscriber.onNext(4); subscriber.onNext(5); subscriber.onCompleted(); } }) .throttleWithTimeout(800, TimeUnit.MILLISECONDS) .subscribeOn(Schedulers.newThread()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(onNextAction);
在这里,我设置的时间间隔指定为800毫秒,所以最后显示的数据是有3、4、5。
4、组合操作符
组合操作符用于将多个Observable组合成一个单一的Observable,在这里我介绍如下图所示5种操作符:
图4.1 组合操作符分类
①startWith组合操作符
startWith组合操作符使用的代码如下所示:
//startWith操作符,会在发送的数据之前插入数据Observable.range(3,5).startWith(0,10086).subscribe(onNextAction);
很简单,会在发送的数据序列前插入数据序列,并且会发送插入的数据序列。
②merge组合操作符
merge组合操作符使用的代码如下所示:
//merge操作符,会将多个Observable对象合并到一个Observable对象中进行发送 ObservablefirstObservable = Observable.just(0, 1, 2).subscribeOn(Schedulers.io()); ObservablesecondObservable = Observable.just(3, 4, 5); Observable.merge(firstObservable, secondObservable).subscribe(onNextAction, onErrorAction);
如下图所示,merge操作符会将多个Observable对象进行合并。
图2.4.2 merge操作符示意图
需要注意的是:merge可能会让合并的Observables发射的数据交错。
在这里我将firstObservable指定在IO线程中进行发送,secondObservable没有指定线程,两者合并然后发送数据时便会产生数据交错的现象。
③concat组合操作符
concat组合操作符使用的代码如下所示:
//concat操作符,会将多个Observable对象合并到一个Observable对象中进行发送,严格按照顺序进行发送 ObservablefirstObservable = Observable.just(0, 1, 2).subscribeOn(Schedulers.io()); ObservablesecondObservable = Observable.just(3, 4, 5); Observable.concat(firstObservable, secondObservable) .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(onNextAction);
concat操作符不同于merge操作符的区别就是:会将多个Observable对象合并到一个Observable对象中进行发送,严格按照顺序进行发送。如下图所示,直到第一个Observable发送完毕数据后,第二个Observable才会进行数据的发送。
图2.4.3 concat组合操作符
④zip组合操作符
zip组合操作符使用的代码如下所示:
//zip操作符,会将多个Observable对象转换成一个Observable对象然后进行发送,转换关系可根据需求自定义Observable integerObservable = Observable.range(0,4); Observable stringObservable = Observable.just("a","b","c","d"); Observable.zip(integerObservable, stringObservable,newFunc2() { @Override publicStringcall(Integer num,Stringinfo) {//在这里的转换关系为将数字与字串内容进行拼接return"数字为:"+ num +"……字符为:"+ info; } }).subscribe(onNextAction);
image.png
zip操作符返回一个Obversable,它使用这个函数按顺序结合两个或多个Observables发射的数据项,然后它发射这个函数返回的结果。
它按照严格的顺序进行数据发送。它只发射与发射数据项最少的那个Observable一样多的数据。
⑤combineLastest组合操作符
combineLastest组合操作符使用的代码如下所示:
//combineLastest操作符,会将多个Observable对象转换一个Observable对象然后进行发送,转换关系可以根据需求自定义//不同于zip操作符的是,会将最新发送的数据组合到一起integerObservable = Observable.just(1,2,3); stringObservable = Observable.just("a","b","c"); Observable.combineLatest(integerObservable, stringObservable,newFunc2() { @Override publicStringcall(Integer num,Stringinfo) {//在这里的转换关系为将数字与字串内容进行拼接return"数字为:"+ num +"……字符为:"+ info; } }).subscribe(onNextAction);
当两个Observables中的任何一个发射了数据时,使用一个函数结合每个Observable发射的最近数据项,并且基于这个函数的结果发射数据。可在本案例代码中进行验证。
5、辅助操作符
辅助操作符就是处理Observable的帮助动作,在这里介绍如下5种辅助操作符。
图2.5 辅助操作符分类
①delay操作符
delay操作符使用的代码如下所示:
//delay操作符可以让源Observable对象发送数据之前暂停一段制定的时间Observable.just(1,2,3) .delay(2, TimeUnit.SECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe(onNextAction);
在这里我将延时时间设置为2秒,延迟指定的时间后发射源Observable中的数据。
②do操作符
do操作符使用的代码如下所示:
//doOnNext是do操作符中的一种 Observable.range(0, 3).doOnNext(onNextAction).subscribe(onNextAction);
do操作符,其下细分有很多内容,以doOnNext为例,其作用就是为源Observable对象发送数据后,当Subscriber接收到数据时,即当Subscriber的onNext方法被调用时,提供回调相应数据。
③subscribeOn辅助操作符
④observeOn辅助操作符
subscribeOn、observeOn操作符使用的代码如下所示:
Observable.just("当前的线程ID为" +Thread.currentThread().getName()).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(onNextAction);
subscribeOn操作符,指定subscribe()所发生的线程,即Observable.OnSubscribe被激活时所处的线程。或者叫做事件产生的线程。
observeOn操作符,指定Subscriber所运行的线程。或者叫做事件消费的线程。
上篇文章中我提到Schedulers可以使得RxJava实现线程切换,实质上就是借助于lift变换方法进行转换,subscribeOn发生在下图的通知过程,observeOn发生在下图中的发送过程。
图2.5.4 Observable与Subscriber的转换关系图
⑤timeout辅助操作符
timeout操作符使用的代码如下所示:
//timeout操作符,如果源Observable对象过了一段时间没有发送数据,timeout会以onError通知终止这个ObservableObservable.create(newObservable.OnSubscribe() {@Overridepublicvoidcall(Subscriber subscriber){for(inti =0; i <5; i++) {try{ Thread.sleep(i *100); }catch(InterruptedException e) { e.printStackTrace(); } subscriber.onNext(i); } } }).timeout(200, TimeUnit.MILLISECONDS, Observable.just(100,200)) .observeOn(AndroidSchedulers.mainThread()) .subscribe(onNextAction);
需要强调的一点是,在这里timeout(long timeout, TimeUnit timeUnit, Observable other)是timeout其中的一种,它在超时的时候会将源Observable转换为备用的Observable对象进行发送。
6、错误操作符
图2.6 错误操作符的分类
①catch操作符
实质上在这里catch操作符细分有三种实现方案:onErrorReturn、onErrorResumeNext、onExceptionResumeNext。
首先分析onErrorReturn的代码:
Observable.create(newObservable.OnSubscribe() {@Overridepublicvoidcall(Subscriber subscriber){for(inti =0; i <5; i++) {if(i >3) { subscriber.onError(newThrowable("User Alex Defined Error")); } subscriber.onNext(i); } } }).onErrorReturn(newFunc1() {@OverridepublicIntegercall(Throwable throwable){return404; } }).subscribe(onNextAction, onErrorAction, onCompletedAction);
onErrorReturn操作符,会在遇到错误时,停止源Observable的,并调用用户自定义的返回请求,实质上就是调用一次OnNext方法进行内容发送后,停止消息发送。
然后分析onErrorResumeNext的代码:
Observable.create(newObservable.OnSubscribe() {@Overridepublicvoidcall(Subscriber subscriber){for(inti =0; i <5; i++) {if(i >3) { subscriber.onError(newThrowable("User Alex Defined Error")); } subscriber.onNext(i); } } }).onErrorResumeNext(newFunc1>() {@OverridepublicObservable call(Throwable throwable) {returnObservable.just(100,101,102); } }).subscribe(onNextAction,onErrorAction,onCompletedAction);
onErrorResumeNext操作符,会在源Observable遇到错误时,立即停止源Observable的数据发送,并取用新的Observable对象进行新的数据发送。
最后,分析onExceptionResumeNext的代码:
Observable.create(newObservable.OnSubscribe() {@Overridepublicvoidcall(Subscriber subscriber){for(inti =0; i <5; i++) {if(i >3) { subscriber.onError(newThrowable("User Alex Defined Error")); } subscriber.onNext(i); } } }).onExceptionResumeNext(Observable.just(100,101,102)).subscribe(onNextAction,onErrorAction,onCompletedAction);
onExceptionResumeNext,会将错误发给Observer,而不会调用备用的Observable
②retry操作符
retry操作符实现的代码如下所示:
//retry操作符,当遇到exception时会进行重试,重试次数可以由用户进行定义Observable.create(newObservable.OnSubscribe() {@Overridepublicvoidcall(Subscriber subscriber){for(inti =0; i <5; i++) {if(i >1) { subscriber.onError(newThrowable("User Alex Defined Error")); } subscriber.onNext(i); } } }).retry(2).subscribe(onNextAction,onErrorAction,onCompletedAction);
retry操作符不会将原始Observable的onError通知传递给观察者,它会重新订阅这个Observable。
图2.6.2 retry操作符示意图
7、布尔操作符
布尔操作符根据给定规则进行判断,是否符合规则然后返回布尔值。布尔操作符意义简单操作简便在这里介绍如下5种:
图2.7 布尔操作符分类
①all操作符
all操作符实现的代码如下所示:
Observable.just(1,2,3,4).all(newFunc1() {@OverridepublicBooleancall(Integer num){returnnum >3; } }).subscribe(onNextAction, onErrorAction, onCompletedAction);
all操作符,对源Observable发送的每一个数据根据给定的条件进行判断。如果全部符合条件,返回true,否则返回false。
②contains操作符
contains操作符实现的代码如下所示:
Observable.just(1, 2, 3, 4).contains(2).subscribe(onNextAction,onErrorAction,onCompletedAction);
contains操作符,对源Observable发送的数据是否包含定义的选项进行判断。如果包含返回true,否则返回false。
③isEmpty操作符
isEmpty操作符实现的代码如下所示:
Observable.just(1, 2, 3, 4).isEmpty().subscribe(onNextAction,onErrorAction,onCompletedAction);
isEmpty操作符,对源Observable发送的数据是否为空进行判断。如果源Observable发送的数据为空返回true,否则返回false。
④exists操作符
exists操作符实现的代码如下所示:
Observable.just(1,2,3,4).exists(newFunc1() {@OverridepublicBooleancall(Integer num){returnnum >3; } }).subscribe(onNextAction, onErrorAction, onCompletedAction);
exists操作符,对源Observable发送的单独一个数据根据给定的条件进行判断。如果有一个数据符合条件,返回true,否则返回false。
⑤sequenceEqual操作符
sequenceEqual操作符实现的代码如下所示:
Observable.sequenceEqual(Observable.just(1, 2, 3, 4),Observable.just(1)).subscribe(onNextAction,onErrorAction,onCompletedAction);
sequenceEqual操作符,对两个Observable进行判断,两个Observable相同时返回true,否则返回false。这里包含两个Observable的数据,发射顺序,终止状态是否相同。
8、条件操作符
图2.8 条件操作符
①amb操作符
amb操作符实现的代码如下所示:
//给定多个Observable,只让第一个发送数据的Observable发送数据Observable .amb(Observable.range(0,3).delay(2000, TimeUnit.MILLISECONDS),Observable.range(100,3)) .subscribe(onNextAction);
如下图所示,首先发送通知给Amb的那个,不管发射的是一项数据还是一个onError或onCompleted通知。Amb将忽略和丢弃其它所有Observables的发射物。
图2.8.1 amb操作符示意图
②defaultIfEmpty操作符
amb操作符实现的代码如下所示:
//如果源Observable没有发送数据,则发送一个默认数据Observable.create(newObservable.OnSubscribe() {@Overridepublicvoidcall(Subscriber subscriber){ subscriber.onCompleted(); } }).defaultIfEmpty(404).subscribe(onNextAction,onErrorAction,onCompletedAction);
9、转换操作符
转换操作符可以将Observable转换为其它的对象或数据结构。在这里介绍如下所示三种转换操作符:
图2.9 转换操作符的分类
①toList操作符
toList操作符实现的代码如下所示:
//toList操作符,将源Observable发送的数据组合为一个List集合//然后再次在onNext方法中将转换完的List集合进行传递Observable.just(1,2,3).toList().subscribe(newAction1>() {@Overridepublicvoidcall(List numList){for(Integer i : numList) { Toast.makeText(getActivity(),"i:"+ i, Toast.LENGTH_SHORT).show(); } } });
通常,发射多项数据的Observable会为每一项数据调用onNext方法。你可以用toList操作符改变这个行为,让Observable将多项数据组合成一个List,然后调用一次onNext方法传递整个列表。
②toSortedList操作符
toSortedList操作符实现的代码如下所示:
//toSortedList操作符,会将源Observable发送的数据组合为一个List集合,并会按照升序的方式进行排序//然后再次在onNext方法中将转换完的List集合进行传递Observable.just(40,10,80,30).toSortedList().subscribe(newAction1>() {@Overridepublicvoidcall(List numList){for(Integer i : numList) { Toast.makeText(getActivity(),"i:"+ i, Toast.LENGTH_SHORT).show(); } } });
不同于toList操作符的是,它会对产生的列表排序,默认是自然升序。
③toMap操作符
toMap操作符实现的代码如下所示:
//toMap操作符,将源Observable发送的数据作为Map集合中的值,需要值进行键的定义//将转换完毕的Map集合在onNext方法中进行发送Observable.just("Alex","Payne").toMap(newFunc1() {@OverridepublicIntegercall(String s){returns.equals("Alex")?0:1; } }).subscribe(newAction1>() {@Overridepublicvoidcall(Map convertMap){for(inti =0; i < convertMap.size(); i++) { Toast.makeText(getActivity(), convertMap.get(i), Toast.LENGTH_SHORT).show(); } } });
源Observable发送的数据作为键值对中的值,我们可以提供一个用于生成Map的Key的函数,然后不同的键存储源Observable发送的不同的值。
toMap默认不在任何特定的调度器上执行。
图2.9.3 toMap操作符示意图
三、总结
1、在本文中,我结合项目代码详细介绍了部分RxJava的操作符,局部参照:RxJava中文翻译文档。
2、本文中的案例代码已上传Github,欢迎大家star、fork。详情戳→GitHub案例代码。
3、操作符实质上就是RxJava函数式编程模式的体现,Lambda表达式并且可以进一步优化RxJava。
4、在下篇文章中我会对于RxJava进行深层次的剖析,还有RxJava结合例如Retrofit、RxBus等开源框架的内容,希望本文对你在学习RxJava的路上有所启发。
作者:Alex_Payne
链接:https://www.jianshu.com/p/d997805b37d4
來源:
著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。