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

本文深入探讨RxJava中变换操作符的使用方法及其特点,包括map(), flatMap(), concatMap() 和 buffer()等,通过具体示例展示了如何高效地进行数据类型转换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

Map()

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

 Observable.just(1,2,3,4)
                .map(new Function<Integer, String>() {
                    @Override
                    public String apply(Integer integer) throws Exception {
                        return String.valueOf(integer) + "String";
                    }
                }).subscribe(new Consumer<String>() {
            @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<Integer, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(Integer integer) throws Exception {
                        return Observable.just(integer+"String");
                    }
                }).subscribe(new Consumer<String>() {
            @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<Product> 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<Product> 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<Shop, ArrayList<Product>>() {
                    @Override
                    public ArrayList<Product> apply(Shop shop) throws Exception {
                        Log.e("商店名称:", shop.getName()+"售卖商品有:");
                        return shop.getProducts();
                    }
                })
                .subscribe(new Consumer<ArrayList<Product>>() {
                    @Override
                    public void accept(ArrayList<Product> 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<Shop, ObservableSource<Product>>() {
                    @Override
                    public ObservableSource<Product> apply(Shop shop) throws Exception {
                        Log.e("商店名称:", shop.getName()+"售卖商品有:");
                        return Observable.fromIterable(shop.getProducts());
                    }
                })
                .subscribe(new Consumer<Product>() {
            @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<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
                e.onNext(2);
                e.onNext(3);
            }
        }).concatMap(new Function<Integer, ObservableSource<String>>() {
            @Override
            public ObservableSource<String> apply(Integer integer) throws Exception {
                ArrayList<String> strings = new ArrayList<>();
                for (int i = 0; i < 3; i++) {
                    strings.add(integer + "===" + i);
                }
                return Observable.fromIterable(strings);
            }
        })
                .subscribe(new Consumer<String>() {
                    @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<List<Integer>>() {
                    @Override
                    public void accept(List<Integer> 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<List<Integer>, ObservableSource<Integer>>() {
                    @Override
                    public ObservableSource<Integer> apply(List<Integer> integers) throws Exception {
                        return Observable.fromIterable(integers);
                    }
                }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                Log.e("integer = ",integer + "");
            }
        });

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

 

 



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值