Rxjava2.0 再探---操作符
来源:互联网 发布:装修图制作软件 编辑:程序博客网 时间:2024/05/18 16:35
1.前言
上篇主要介绍了Rxjava2.0的Schedulers以及简单的操作符,这篇主要介绍Rxjava的经常使用的操作符。
上篇链接:Rxjava2.0 初探 http://blog.csdn.net/mr_zhang0101/article/details/74639971
2.Rxjava的操作符
Rxjava的操作符数量庞大,此篇介绍一些常用的操作符
先看下这些操作符的变换功效:
变换操作符:map:在接收事件时,变换事件的类型,比如int ---> StringflatMap:将一个事件包装成一个Observable继续发送concatMap:和flatMap类似,可以保证有序scanWith:将发送的每一个事件进行操作,观察者接收操作后的事件过滤操作符:filter:会对要发射的事件进行测试,只有通过测试的数据才会被发射take:只发射前面的部分数据辅助操作符:do:只有执行相应的时候会被调用(下文会详细介绍)delay:延迟一段指定的时间再发射Observable的数据。结合操作符:zip:将多个Observables的发射物结合到一起,基于这个函数的结果为每个结合体发射单个数据项。
2.1 map变换
我们在发送事件可能需要对这些事件就行一些加工,变换,这个时候就可以利用map就行操作了,map是将事件依次进行加工。
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { e.onNext(1); e.onNext(2); e.onNext(3); }}).map(new Function<Integer, String>() { @Override public String apply(Integer integer) throws Exception { return "事件"+integer*3; }}).subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { Log.d(TAG, "accept: "+s); }});
其中map接收的Function泛型的一个参数就是原事件的类型,第二个参数就是要变换的事件类型。运行结果如下:
D/HANDLERACTIVITY: accept: 事件3D/HANDLERACTIVITY: accept: 事件6D/HANDLERACTIVITY: accept: 事件9
这里进行了将发送的Integer*3,并变成String类型。
2.2 flatMap变换
map是将一个事件加工成另外一个类型的事件(也可以变换成同类型的事件),而flatMap是将事件包装成一个Observable继续发送。
Observable.just(1,2,3,4,5,6) .flatMap(new Function<Integer, ObservableSource<String>>() { @Override public ObservableSource<String> apply(Integer integer) throws Exception { final List<String> list = new ArrayList<>(); list.add("事件" + integer); //fromIterable把一个集合的每个item依次发送 //delay延迟发送,辅助操作符,之后会介绍 return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS); } }).subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { Log.d(TAG, "accept: "+s); }});
运行的结果:
D/HANDLERACTIVITY: accept: 事件1D/HANDLERACTIVITY: accept: 事件3D/HANDLERACTIVITY: accept: 事件5D/HANDLERACTIVITY: accept: 事件2D/HANDLERACTIVITY: accept: 事件4D/HANDLERACTIVITY: accept: 事件6
可以发现,flatMap变换后,不能保证事件还是有序得发送,如果需要flatMap的这种效果,又想保证有序发送,就需要concatMap变换了
2.3 concatMap变换
将之前flatMap变换的代码中只将flatMap换成concatMap
Observable.just(1,2,3,4,5,6) .concatMap(new Function<Integer, ObservableSource<String>>() { @Override public ObservableSource<String> apply(Integer integer) throws Exception { final List<String> list = new ArrayList<>(); list.add("事件" + integer); //fromIterable把一个集合的每个item依次发送 //delay延迟发送 return Observable.fromIterable(list).delay(10, TimeUnit.MILLISECONDS); } }).subscribe(new Consumer<String>() { @Override public void accept(String s) throws Exception { Log.d(TAG, "accept: "+s); }});
运行如下:
D/HANDLERACTIVITY: accept: 事件1D/HANDLERACTIVITY: accept: 事件2D/HANDLERACTIVITY: accept: 事件3D/HANDLERACTIVITY: accept: 事件4D/HANDLERACTIVITY: accept: 事件5D/HANDLERACTIVITY: accept: 事件6
不难看出concatMap保证了有序
2.3 scanWith变换
将发送的每一个事件进行操作,接收操作后的事件
Observable.just(1,2,3) .scanWith(new Callable<Integer>() { @Override public Integer call() throws Exception { Log.d(TAG, "call: "); //接收的第一个事件 return 5; } }, new BiFunction<Integer, Integer, Integer>() { //BiFunction代替Rxjava1.0中的Func2 @Override public Integer apply(Integer integer, Integer integer2) throws Exception { Log.d(TAG, "apply: "+"integer=="+integer+";integer2=="+integer2); return integer*integer2; } }).subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.d(TAG, "accept: "+integer); }});
运行结果:
D/HANDLERACTIVITY: call: D/HANDLERACTIVITY: accept: 5D/HANDLERACTIVITY: apply: integer==5;integer2==1D/HANDLERACTIVITY: accept: 5D/HANDLERACTIVITY: apply: integer==5;integer2==2D/HANDLERACTIVITY: accept: 10D/HANDLERACTIVITY: apply: integer==10;integer2==3D/HANDLERACTIVITY: accept: 30
从结果可以看出,scanWith操作符的第一个参数Callable,提供一个会第一次接收到的事件;第二个参数BiFunction中的apply方法第一个参数就是上次操作后的结果,第二个参数就是item的值
2.4 filter过滤
filter会对要发射的事件进行测试,只有通过测试的数据才会被发射,也就是把事件过滤一次。
Observable.just(1, 2, 3, 4, 5, 6) .filter(new Predicate<Integer>() { @Override public boolean test(Integer integer) throws Exception { return (integer<4); } }).subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.d(TAG, "accept: "+integer); }});
运行结果:
D/HANDLERACTIVITY: accept: 1D/HANDLERACTIVITY: accept: 2D/HANDLERACTIVITY: accept: 3
另外,ofType(Class): filter操作符的一个特殊形式。它过滤一个Observable只返回指定类型的数据。
Observable.just(new Integer(1), new String("2"),new Long(3)) .ofType(Integer.class) .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.d(TAG, "accept: "+integer); } });
运行结果:
D/HANDLERACTIVITY: accept: 1
2.5 take过滤
take(int):只发射前面的N项数据,然后发射完成通知,忽略剩余的数据。
takeLast(int): 只发射原始Observable发射的后N项数据,忽略之前的数据。
takeLastBuffer: 它和takeLast类似,唯一的不同是它把所有的数据项收集到一个List再发射
这个比较简单,只举一个take的例子
Observable.just(1, 2, 3, 4, 5, 6) .take(3) .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.d(TAG, "accept: "+integer); } });
运行结果:
D/HANDLERACTIVITY: accept: 1D/HANDLERACTIVITY: accept: 2D/HANDLERACTIVITY: accept: 3
2.6 do辅助
do操作符包括doOnEach、doOnNext、doOnError等
doOnEach:为 Observable注册这样一个回调,当Observable没发射一项数据就会调用它一次,包括onNext、onError和 onCompleted
doOnNext:只有执行onNext的时候会被调用
doOnError:只有执行onError的时候会被调用
Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { e.onNext(1); e.onNext(2); e.onNext(3); e.onError(new Throwable("error")); } }) .doOnNext(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.d(TAG, "doOnNext: " + integer); } }) .doOnEach(new Consumer<Notification<Integer>>() { @Override public void accept(Notification<Integer> integerNotification) throws Exception { Log.d(TAG, "doOnEach: " + integerNotification.getValue()); } }) .doOnError(new Consumer<Throwable>() { @Override public void accept(Throwable throwable) throws Exception { Log.d(TAG, "doOnError: " + throwable.getMessage()); } }).subscribe(new Observer<Integer>() { @Override public void onSubscribe(Disposable d) { Log.d(TAG, "onSubscribe: "); } @Override public void onNext(Integer value) { Log.d(TAG, "subscribe:onNext: "+value); } @Override public void onError(Throwable e) { Log.d(TAG, "subscribe:onError: "+e.getMessage()); } @Override public void onComplete() { Log.d(TAG, "subscribe:onComplete: "); } });
运行结果:
D/HANDLERACTIVITY: onSubscribe: D/HANDLERACTIVITY: doOnNext: 1D/HANDLERACTIVITY: doOnEach: 1D/HANDLERACTIVITY: subscribe:onNext: 1D/HANDLERACTIVITY: doOnNext: 2D/HANDLERACTIVITY: doOnEach: 2D/HANDLERACTIVITY: subscribe:onNext: 2D/HANDLERACTIVITY: doOnNext: 3D/HANDLERACTIVITY: doOnEach: 3D/HANDLERACTIVITY: subscribe:onNext: 3D/HANDLERACTIVITY: doOnEach: nullD/HANDLERACTIVITY: doOnError: errorD/HANDLERACTIVITY: subscribe:onError: error
可以看出do操作符不会拦截事件的传递,观察者还是会接收到事件
2.7 delay辅助
delay的意思就是延迟,这个操作符会延迟一段指定的时间再发射Observable的数据。
final SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> e) throws Exception { Log.d(TAG, "emit:" + sdf.format(new Date())); e.onNext(1); e.onNext(2); e.onNext(3); e.onComplete(); }}).subscribeOn(Schedulers.computation()).delay(2, TimeUnit.SECONDS) .subscribe(new Consumer<Integer>() { @Override public void accept(Integer integer) throws Exception { Log.d(TAG, "delay accept:" + sdf.format(new Date()) + "->" + integer); } });
运行结果:
D/HANDLERACTIVITY: emit:10:17:18D/HANDLERACTIVITY: delay accept:10:17:20->1D/HANDLERACTIVITY: delay accept:10:17:20->2D/HANDLERACTIVITY: delay accept:10:17:20->3
2.8 zip结合
Zip将多个Observables的发射物结合到一起,基于这个函数的结果为每个结合体发射单个数据项。它按照严格的顺序应用这个函数。接收到的数据和发射少的那个一样多。
先写两个发射源a和b:
Observable<Integer> ob1 = Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { Log.d(TAG, "emit 1"); emitter.onNext(1); Log.d(TAG, "emit 2"); emitter.onNext(2); Log.d(TAG, "emit 3"); emitter.onNext(3); Log.d(TAG, "emit complete1"); emitter.onComplete(); }});Observable<String> ob2 = Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> emitter) throws Exception { Log.d(TAG, "emit x"); emitter.onNext("x"); Log.d(TAG, "emit y"); emitter.onNext("y"); Log.d(TAG, "emit complete2"); emitter.onComplete(); }});
zip结合接收事件
Observable.zip(ob1, ob2, new BiFunction<Integer, String, String>() { @Override public String apply(Integer integer, String s) throws Exception { //两个发射的数据的结合方式 return integer +"&"+s; }}).subscribe(new Observer<String>() { @Override public void onSubscribe(Disposable d) { Log.d(TAG, "onSubscribe"); } @Override public void onNext(String value) { Log.d(TAG, "onNext: " + value); } @Override public void onError(Throwable e) { Log.d(TAG, "onError"); } @Override public void onComplete() { Log.d(TAG, "onComplete"); }});
运行结果:
D/HANDLERACTIVITY: onSubscribeD/HANDLERACTIVITY: emit 1D/HANDLERACTIVITY: emit 2D/HANDLERACTIVITY: emit 3D/HANDLERACTIVITY: emit complete1D/HANDLERACTIVITY: emit xD/HANDLERACTIVITY: onNext: 1&xD/HANDLERACTIVITY: emit yD/HANDLERACTIVITY: onNext: 2&yD/HANDLERACTIVITY: emit complete2D/HANDLERACTIVITY: onComplete
从结果可以看出,由于在一个线程中,所以发射源a发射完数据后,发射源b才开始发射,接收的个数和发射源b发射的个数一样(个数较a少),那么换成不同的线程,怎么发射的呢?
Observable<Integer> ob1 = Observable.create(new ObservableOnSubscribe<Integer>() { @Override public void subscribe(ObservableEmitter<Integer> emitter) throws Exception { Log.d(TAG, "emit 1"); emitter.onNext(1); Log.d(TAG, "emit 2"); //为了排除程序执行过快线程未切换,这里适当添加一些停顿 Thread.sleep(200); emitter.onNext(2); Log.d(TAG, "emit 3"); Thread.sleep(200); emitter.onNext(3); Log.d(TAG, "emit complete1"); emitter.onComplete(); }}).subscribeOn(Schedulers.io());Observable<String> ob2 = Observable.create(new ObservableOnSubscribe<String>() { @Override public void subscribe(ObservableEmitter<String> emitter) throws Exception { Log.d(TAG, "emit x"); emitter.onNext("x"); Thread.sleep(200); Log.d(TAG, "emit y"); emitter.onNext("y"); Thread.sleep(200); Log.d(TAG, "emit complete2"); emitter.onComplete(); }}).subscribeOn(Schedulers.io());Observable.zip(ob1, ob2, new BiFunction<Integer, String, String>() { @Override public String apply(Integer integer, String s) throws Exception { //两个发射的数据的结合方式 return integer +"&"+s; }}).subscribe(new Observer<String>() { @Override public void onSubscribe(Disposable d) { Log.d(TAG, "onSubscribe"); } @Override public void onNext(String value) { Log.d(TAG, "onNext: " + value); } @Override public void onError(Throwable e) { Log.d(TAG, "onError"); } @Override public void onComplete() { Log.d(TAG, "onComplete"); }});
执行结果:
D/HANDLERACTIVITY: onSubscribeD/HANDLERACTIVITY: emit 1D/HANDLERACTIVITY: emit 2D/HANDLERACTIVITY: emit xD/HANDLERACTIVITY: onNext: 1&xD/HANDLERACTIVITY: emit 3D/HANDLERACTIVITY: emit yD/HANDLERACTIVITY: onNext: 2&yD/HANDLERACTIVITY: emit complete1D/HANDLERACTIVITY: emit complete2D/HANDLERACTIVITY: onComplete
从结果可以看出,只要组成一对,就会接收到一个组合的数据。
操作符就介绍这些常用的,如果想了解更多,请阅读:http://blog.csdn.net/u010163442/article/category/6270573
Demo地址:https://github.com/Mr-zhang0101/Rxjava2.0Test
- Rxjava2.0 再探---操作符
- RxJava2.0教程操作符
- RxJava2 / RxJava2操作符scan
- rxjava2操作符
- RxJava2操作符Map
- RxJava2 / RxAndroid2操作符take
- RxJava2 / RxAndroid2操作符skip
- RxJava2 / RxAndroid2操作符skip
- RxJava2 / RxAndroid2操作符skip
- RxJava2操作符之“Delay”
- Rxjava2操作符入门(一)
- 从零开始的RxJava2.0教程(二)操作符
- 从零开始的RxJava2.0教程(二)操作符
- 从零开始的RxJava2.0教程(二)操作符
- 从零开始的RxJava2.0教程(二)操作符
- RxJava2.0中create操作符用法和源码分析
- RxJava2 / RxAndroid2操作符distinct去重
- RxJava2.x使用以及操作符详解
- 腾讯云直播初体验
- Android视频直播的实现
- BZOJ 2850: 巧克力王国 kdtree
- iOS调用QQ客户端,发起临时会话
- RxBus基于Rxjava2.0---支持Sticky事件
- Rxjava2.0 再探---操作符
- keras上的RNN代码理解
- 用Qt开发安卓应用,是不是不成熟?有什么缺陷?
- 怎样使用Delphi让应用程序不在系统任务条上显示呢?
- jdbc的批量操作
- centos7 scrapy 创建项目报错 TLSVersion.TLSv1_1: SSL.OP_NO_TLSv1_1,
- JAVA中使用JSON进行数据传递
- 逆波兰表达式
- POJ 3250 Bad Hair Day (单调栈)