Android框架源码分析——RxJava 操作符使用

概述:上篇文章简单的介绍了Rxjava中Observable的创建操作符的使用和其代表的意义,因为比较简单所以写的比较粗略,本文将继续介绍一些关于类型变换的操作符,变换操作符的强大支出在于不需要额外的处理,可以快速的将数据进行处理和转换,得到需要的类型且代码和逻辑清晰易懂,引用网上的一张图片:

Android框架源码分析——RxJava 操作符使用_第1张图片

Map()

map():实现对发送的数据按照一定的规则进行转换,达到输出不同的类型

 Observable.just(1,2,3,4)
                .map(new Function() {
                    @Override
                    public String apply(Integer integer) throws Exception {
                        return String.valueOf(integer) + "String";
                    }
                }).subscribe(new Consumer() {
            @Override
            public void accept(String s) throws Exception {
                
            }
        });

输出结果:

02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 1String
02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 2String
02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 3String
02-05 11:19:58.702 30540-30540/com.example.administrator.sdk E/===: 4String

FlatMap()

flatMap():也可实现类型的装换,但功能比map()更加强大,它要求返回的时被Observable包裹的类型数据,用法:

 Observable.just(1,2,3,4)
                .flatMap(new Function>() {
                    @Override
                    public ObservableSource apply(Integer integer) throws Exception {
                        return Observable.just(integer+"String");
                    }
                }).subscribe(new Consumer() {
            @Override
            public void accept(String s) throws Exception {
                Log.e("flat===", s);
            }
        });

flatMap()与map() 的不同:

  • 返回类型不同:从上面的两个代码可以看出两者的返回 类型不同,map()返回的是要返回的具体数据,而flatMap()返回的是被Observable包裹的数据,因此可以继续分发数据
  • 功能更强大:因为返回的仍然是Observable,所以使用更加灵活方便

实例:有一组店铺集合,每个店铺售卖多种商品,数据源如下:

private void initData() {
        Product phone_apple = new Product("手机");
        Product computer_apple = new Product("电脑");
        Product pad_apple = new Product("平板");
        ArrayList products_apple = new ArrayList<>();
        products_apple.add(phone_apple);
        products_apple.add(computer_apple);
        products_apple.add(pad_apple);
        apple = new Shop("苹果", products_apple);

        Product phone_xiaomi = new Product("手机");
        Product computer_xiaomi = new Product("电脑");
        Product pad_xiaomi = new Product("平板");
        Product light_xiaomi = new Product("灯");
        ArrayList products_xiaomi = new ArrayList<>();
        products_xiaomi.add(phone_xiaomi);
        products_xiaomi.add(computer_xiaomi);
        products_xiaomi.add(pad_xiaomi);
        products_xiaomi.add(light_xiaomi);
        xiaomi = new Shop("苹果", products_xiaomi);
    }

现在要打印每家店铺的商品名称,使用map实现:

  Observable.fromIterable(shops)
                .map(new Function>() {
                    @Override
                    public ArrayList apply(Shop shop) throws Exception {
                        Log.e("商店名称:", shop.getName()+"售卖商品有:");
                        return shop.getProducts();
                    }
                })
                .subscribe(new Consumer>() {
                    @Override
                    public void accept(ArrayList products) throws Exception {
                        for (Product product : products) {
                            Log.e("Product == ", product.getName());
                        }
                    }
                });

输出结果:

02-05 11:58:15.916 31479-31479/? E/==:  --------------------------map-----------------------------
02-05 11:58:15.930 31479-31479/? E/商店名称:: 苹果售卖商品有:
02-05 11:58:15.930 31479-31479/? E/Product ==: 手机
02-05 11:58:15.930 31479-31479/? E/Product ==: 电脑
02-05 11:58:15.930 31479-31479/? E/Product ==: 平板
02-05 11:58:15.930 31479-31479/? E/商店名称:: 苹果售卖商品有:
02-05 11:58:15.930 31479-31479/? E/Product ==: 手机
02-05 11:58:15.930 31479-31479/? E/Product ==: 电脑
02-05 11:58:15.930 31479-31479/? E/Product ==: 平板
02-05 11:58:15.930 31479-31479/? E/Product ==: 灯

使用flatMap实现:

 Observable.fromIterable(shops)
                .flatMap(new Function>() {
                    @Override
                    public ObservableSource apply(Shop shop) throws Exception {
                        Log.e("商店名称:", shop.getName()+"售卖商品有:");
                        return Observable.fromIterable(shop.getProducts());
                    }
                })
                .subscribe(new Consumer() {
            @Override
            public void accept(Product product) throws Exception {
                Log.e("Product == ", product.getName());
            }
        });

输出结果:

02-05 11:58:15.931 31479-31479/? E/==:  --------------------------flatMap-----------------------------
02-05 11:58:15.937 31479-31479/? E/商店名称:: 苹果售卖商品有:
02-05 11:58:15.937 31479-31479/? E/Product ==: 手机
02-05 11:58:15.937 31479-31479/? E/Product ==: 电脑
02-05 11:58:15.937 31479-31479/? E/Product ==: 平板
02-05 11:58:15.937 31479-31479/? E/商店名称:: 苹果售卖商品有:
02-05 11:58:15.937 31479-31479/? E/Product ==: 手机
02-05 11:58:15.937 31479-31479/? E/Product ==: 电脑
02-05 11:58:15.938 31479-31479/? E/Product ==: 平板
02-05 11:58:15.938 31479-31479/? E/Product ==: 灯

结论:上面使用map实现时只能返回Product的集合,要想输出每个商品需要使用循环去遍历,而使用flatMap的那个获得每个商店后直接再次采用Observable分发他们的商品,然后在观察者直接输出商品名称即可,更简单更清晰

ConcatMap()

与flatMap的使用相同,其别在于flatMap在变换之后会生成一组新的数据序列,顺序与发送的可能会不同,而ConcatMap产生的顺序与发送的顺序一致;

 

Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter e) throws Exception {
                e.onNext(1);
                e.onNext(2);
                e.onNext(3);
            }
        }).concatMap(new Function>() {
            @Override
            public ObservableSource apply(Integer integer) throws Exception {
                ArrayList strings = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    strings.add(integer + "===" + i);
                }
                return Observable.fromIterable(strings);
            }
        })
                .subscribe(new Consumer() {
                    @Override
                    public void accept(String s) throws Exception {
                        Log.e("Integer==", s);
                    }
                });

输出结果:

02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 1===0
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 1===1
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 1===2
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 2===0
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 2===1
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 2===2
02-05 12:19:05.148 32258-32258/com.example.administrator.sdk E/Integer==: 3===0
02-05 12:19:05.149 32258-32258/com.example.administrator.sdk E/Integer==: 3===1
02-05 12:19:05.149 32258-32258/com.example.administrator.sdk E/Integer==: 3===2

Buffer()

每次提取一部分数据到缓存中,发送直接从缓存发送  参数:容量,步长

Observable.just(1,2,3,4,5,6)
                .buffer(3,2)
                .subscribe(new Consumer>() {
                    @Override
                    public void accept(List integers) throws Exception {
                        Log.e("integers===", integers.size()+"");
                        for (Integer integer : integers){
                            Log.e("integer = ",integer + "");
                        }
                    }
                });

按照上面的逻辑,缓存长度为3,第一次,1,2,3,每次取两个,第二个为3,4,5,依次类推:

02-05 13:47:53.107 1123-1123/? E/integers===: 3
02-05 13:47:53.107 1123-1123/? E/integer =: 1
02-05 13:47:53.107 1123-1123/? E/integer =: 2
02-05 13:47:53.107 1123-1123/? E/integer =: 3
02-05 13:47:53.107 1123-1123/? E/integers===: 3
02-05 13:47:53.107 1123-1123/? E/integer =: 3
02-05 13:47:53.108 1123-1123/? E/integer =: 4
02-05 13:47:53.108 1123-1123/? E/integer =: 5
02-05 13:47:53.108 1123-1123/? E/integers===: 2
02-05 13:47:53.108 1123-1123/? E/integer =: 5
02-05 13:47:53.108 1123-1123/? E/integer =: 6

当看到最后返回的是个集合,有没有想到上面的flatMap,可以不需要使用集合的循环就可以直接输出,现在改写:

Observable.just(1,2,3,4,5,6)
                .buffer(3,2)
                .flatMap(new Function, ObservableSource>() {
                    @Override
                    public ObservableSource apply(List integers) throws Exception {
                        return Observable.fromIterable(integers);
                    }
                }).subscribe(new Consumer() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.e("integer = ",integer + "");
            }
        });

到此RxJava中的变换的操作符介绍完了,变换操作符在使用中比较方便,也能满足很多实际开发时的需求,之后会继续介绍其它操作符。

 

 



 

你可能感兴趣的:(Android框架源码分析——RxJava 操作符使用)