从零学习RxJava2.0-变换操作符

RxJava-变换操作符

  • 对事件序列中的事件 / 整个事件序列 进行加工处理(即变换),使得其转变成不同的事件 / 整个事件序列
  • 还是直接看代码效果吧

变换操作符1:map

  • 对 被观察者发送的每1个事件都通过 指定的函数 处理,从而变换成另外一种事件
Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }
        }).map(new Function<Integer, String>() {
            @Override
            public String apply(Integer integer) throws Exception {
                return "使用map操作符将Integer类型的事件 "+integer +" 变成String类型";
            }
        }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                Log.d(TAG, "accept: 消息是String类型的 == " + s );
            }
        });
  • log信息
消息是String类型的 == 使用map操作符将Integer类型的事件 1 变成String类型
消息是String类型的 == 使用map操作符将Integer类型的事件 2 变成String类型
消息是String类型的 == 使用map操作符将Integer类型的事件 3 变成String类型
  • 可以看到,在创建被观察者和订阅观察者之间,增加了一个map方法,使得我们一开始创建的整型类型的时间通过map方法中我们自己编写的逻辑,将他变成了字符串类型
  • 当然不只是从整型转字符串,只要泛型支持,我们都可以去转换

变换操作符2:FlatMap

  • 将被观察者发送的事件序列进行 拆分 & 单独转换,再合并成一个新的事件序列,最后再进行发送
Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                emitter.onNext(1);
                emitter.onNext(2);
                emitter.onNext(3);
            }
        }).flatMap(new Function<Integer, ObservableSource<?>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                final List<String> list = new ArrayList<>();
                list.add("我是事件 " + integer);
                return Observable.fromIterable(list);
            }
        }).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {
                Log.d(TAG, "accept: == " + (String) o) ;
            }
        });
  • log信息
 accept: == 我是事件 1
 accept: == 我是事件 2
 accept: == 我是事件 3
  • 这个方法不看源码的话着实对他的机制很难猜测,经过了一系列的实验,我大概说说我的理解吧
  • 中间调用的flatMap方法其实是不影响自身与观察者的订阅时机的,也就是说,不管你中间加不加这个方法,我订阅的时机(也就是观察者的Subscriber方法执行的时间)是不会变的
  • 那么中间的这个FlatMap方法在这里的主要工作是干什么呢,只不过在每次观察者接收到消息前先经过FlatMap这个方法,然后FlatMap这个方法再将消息处理之后再给观察者的onNext 方法
  • 可以看到我在FlatMap方法里面只写了两句话,创建新的ArrayList,添加数据,重新发送出去
  • 大概的顺序是,被观察者的subscribe方法->观察者的onSubscribe方法->被观察者的subscribe里面具体的第一条onNext语句,然后FlatMap的方法拦截,处理,重新发送->观察者的onNext方法
  • 具体的使用细节,还是在用的时候具体实验吧
  • 这里又说这个方法最终产生的消息顺序是无序的,也就是说不是按照原来的序列,不过我试了好几次都没发现

变换操作符3:ConcatMap

  • 使用方法与上个FlatMap完全相同,在用法上只是说新产生的消息序列与原来序列相同

变换操作符4:Buffer

  • 定期从 被观察者(Obervable)需要发送的事件中 获取一定数量的事件 & 放到缓存区中,最终发送
Observable.just(1,2,3,4,5,6,7)
                .buffer(4,4)
                .subscribe(new Consumer<List<Integer>>() {
                    @Override
                    public void accept(List<Integer> integers) throws Exception {
                        Log.d(TAG, "accept: " + integers.toString());
                    }
                });
  • log信息为
accept: [1, 2, 3, 4]
accept: [5, 6, 7]
  • 所以,两个参数的意思表示,第一个参数表示缓存区的大小是4,最多只能存四个,第二个参数表示从发来的事件序列中读取四次,然后一次性发送的观察者的onNext方法,注意这里第二个参数是读取的次数,而不代表就一定能读取到缓存区,如果缓存区没空间了,那么他的那一次读取是没有存到数据的
  • 同样,这个方法还有好多个重载方法,这里我们常用的就这个和一个参数的,一个参数直接表示缓存区的大小,也就是缓存区满了就直接一次性发送

总结

  • 简单来说,操作符的用法就是使我们之前的消息队列经过一层我们人为的过滤,或者说处理,使得更为我们所更好的利用

猜你喜欢

转载自blog.csdn.net/asffghfgfghfg1556/article/details/81215881