Android面试ericsson

RxJava——操作符篇

2018-07-20  本文已影响242人  无求_95dd

一、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

來源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

上一篇下一篇

猜你喜欢

热点阅读