RxJava在项目中的使用1-------操作符(创建类、变换类)

在之前使用Retrofit的时候,简答介绍了一下RxJava的使用,通过CallAdapterFactory()使得RxJava适配Android平台,也就是RxAndroid这个概念,在之前接触到这里的时候,我说过,RxJava最大的优点,就是多样的操作符,可以得到我们想要的数据类型,返回到UI层,所以从这节开始,我就介绍一下RxJava中,那些最常用的操作符。

implementation 'io.reactivex.rxjava2:rxjava:2.1.0'
implementation 'io.reactivex.rxjava2:rxandroid:2.0.1'
implementation 'com.squareup.retrofit2:adapter-rxjava2:2.7.1'

1、如何理解操作符

在使用RxJava时,我们最常用的三个对象:Observable(被观察者)、Observer(观察者)、subscribe(订阅),通过链式调用,Observable就可以看做是数据发射源,源源不断的数据从上游留到下游,观察者在下游接收这些数据,对于一些原始数据类型,并不是UI层想要的,需要进行数据转换,才会更新在UI层,这个时候,操作符的作用就来了。

RxJava给我们提供了丰富的操作符类型:

Creating 创建操作 - Create/Defer/From/Just/Start/Repeat/Range
Transforming 变换操作 - Buffer/Window/Map/FlatMap/GroupBy/Scan
Filtering 过滤操作 - Debounce/Distinct/Filter/Sample/Skip/Take
Combining 结合操作 - And/StartWith/Join/Merge/Switch/Zip
Error Handling 错误处理 - Catch/Retry
Utility 辅助操作 - Delay/Do/ObserveOn/SubscribeOn/Subscribe
Conditional 条件和布尔操作 - All/Amb/Contains/SkipUntil/TakeUntil
Mathematical 算术和聚合操作 - Average/Concat/Count/Max/Min/Sum/Reduce
Async 异步操作 - Start/ToAsync/StartFuture/FromAction/FromCallable/RunAsync
Connect 连接操作 - Connect/Publish/RefCount/Replay
Convert 转换操作 - ToFuture/ToList/ToIterable/ToMap/toMultiMap
Blocking 阻塞操作 - ForEach/First/Last/MostRecent/Next/Single/Latest
String 字符串操作 - ByLine/Decode/Encode/From/Join/Split/StringConcat

那么接下来,我就逐一介绍一下各类操作符的用法。

1、创建类操作符

(1)create
这个是最常见的、最常用的操作符,用来创建一个Observable对象

(2)just
just操作符其实就是一个数据发射器,创建一个发射指定数据的Observable。

 Observable.just(1,2,3)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        System.out.println("得到的值:"+integer);
                    }
                });

结果:

得到的值:1
得到的值:2
得到的值:3

结果就是将1,2,3(指定的数据)依次发射出来,在下游接收数据。

如果是list集合,会是什么样的呢?

 List<Integer> list =new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        Observable.just(list)
                .subscribe(new Consumer<List<Integer>>() {
                    @Override
                    public void accept(List<Integer> integers) throws Exception {
                        System.out.println("得到的数据:"+integers);
                    }
                });

结果:

得到的数据:[1, 2, 3]

可以看到的是,并没有将数据一个一个地发射出来,而是形成一个数组,如果想要一个一个地输出,需要使用下面的from操作符。

(3)from

其实和just一样,都是将一组数据发射出来,但是from操作符可以将一个相同类型数据的数组发射出来。

fromArray:发射数组

Integer[] items = {1,2,3,4,5};
        Observable.fromArray(items)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        System.out.println("得到的值为:"+integer);
                    }
                });

结果:

得到的值为:1
得到的值为:2
得到的值为:3
得到的值为:4
得到的值为:5

----fromIterable:发送集合数据

List<Integer> list =new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        Observable.fromIterable(list)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        System.out.println("得到的值为:"+integer);
                    }
                });

结果:

得到的值为:1
得到的值为:2
得到的值为:3

(4)defer

defer操作符,指的是在观察者订阅之后,才会创建Observable对象。

 Observable<Object> observale = Observable.defer(new Callable<ObservableSource<?>>() {
            @Override
            public ObservableSource<?> call() throws Exception {
                return Observable.just(str);
            }
        });
       observale.subscribe(new Consumer<String>() {
           @Override
           public void accept(String s) throws Exception {
               System.out.println("得到的数据:"+s);
           }
       });

结果:

得到的数据:null

将str赋值,str = “123”
结果:

得到的数据:123

也就是说在观察者订阅之后,才创建了观察者对象,然后把数据输出,如果是justfrom操作符,在调用这些操作之后就会创建被观察者对象,不管之后是否订阅。

(5)Range、repeat

重复几次发射一个范围的数据。

Observable.range(1,5).repeat(2)
               .subscribe(new Consumer<Integer>() {
                   @Override
                   public void accept(Integer integer) throws Exception {
                       System.out.println("得到的数据:"+integer);
                   }
               });

结果:

得到的数据:1
得到的数据:2
得到的数据:3
得到的数据:4
得到的数据:5
得到的数据:1
得到的数据:2
得到的数据:3
得到的数据:4
得到的数据:5

2、变换类操作符

(1)map

map通常是用来做数据变换,例如将上游的数据都加上一个字符串然后输出。

List<Integer> list =new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        Observable.fromIterable(list)
                .map(new Function<Integer, String>() {
                    @Override
                    public String apply(Integer integer) throws Exception {
                        return integer+"晚上好";
                    }
                }).subscribe(new Consumer<String>() {
            @Override
            public void accept(String s) throws Exception {
                System.out.println("转换后的数据:"+s);
            }
        });

结果:

转换后的数据:1晚上好
转换后的数据:2晚上好
转换后的数据:3晚上好

map就是将整型数据转换为字符串,最终输出。

(2)flatMap

跟map不一样的是,flatMap通常是用来做事件的变换,还是拿上一个例子说明:

List<Integer> list =new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        Observable.fromIterable(list)
               .flatMap(new Function<Integer, ObservableSource<?>>() {
                   @Override
                   public ObservableSource<?> apply(Integer integer) throws Exception {
                       List<String> list  = new ArrayList<>();
                       list.add(integer+"晚上好");
                       return Observable.fromIterable(list);
                   }
               }).subscribe(new Consumer<Object>() {
            @Override
            public void accept(Object o) throws Exception {
                System.out.println("得到的数据:"+o);
            }
        });

结果:

得到的数据:1晚上好
得到的数据:2晚上好
得到的数据:3晚上好

数据都是一样的,但是性质完全不同;在map中,是将数据类型转换后,直接return到下游输出;但是FlatMap return的不是数据,而是新创建的一个Observable对象,将新转换的数据源发射出来,也就是说flatMap是将一个Observable对象转换为了另一个Observable对象,所以利用这个性质,可以做嵌套网络请求
此外concatMap同样也是用于事件变换,只不过concatMap对于顺序有要求。

(3)scan

Scan操作符对原始Observable发射的第一项数据应用一个函数,然后将那个函数的结果作为自己的第一项数据发射。它将函数的结果同第二项数据一起填充给这个函数来产生它自己的第二项数据。它持续进行这个过程来产生剩余的数据序列。

List<Integer> list =new ArrayList<>();
        list.add(1);
        list.add(5);
        list.add(3);
        Observable.fromIterable(list)
               .scan(new BiFunction<Integer, Integer, Integer>() {
                   @Override
                   public Integer apply(Integer integer, Integer integer2) throws Exception {
                       return integer + integer2;
                   }
               }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(Integer integer) throws Exception {
                System.out.println("接收的数据:"+integer);
            }
        });

结果:

接收的数据:1
接收的数据:6
接收的数据:9

看到结果你们应该就懂了:将原始Observable发射的第一个数据1应用于函数,1+0 = 1输出,然后将结果和发射的第个2数据应用于函数 1+5 = 6输出,然后将结果和发射的第3个数据应用于函数 6 +3 = 9.

(4)groupBy

将数据进行分组

List<Integer> list =new ArrayList<>();
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        Observable.fromIterable(list)
                .groupBy(new Function<Integer, Integer>() {
                    @Override
                    public Integer apply(Integer integer) throws Exception {
                        return integer % 2;
                    }
                }).subscribe(new Consumer<GroupedObservable<Integer, Integer>>() {
            @Override
            public void accept(GroupedObservable<Integer, Integer> group) throws Exception {
                group.subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        System.out.println("分组:"+group.getKey()+"  接收到的数据:"+integer);
                    }
                });
            }
        });

通过groupBy来设计分组规则,这里是将数据分为2组,然后得到一个GroupedObservable(分组被观察者对象),然后订阅后得到分组的结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Awesome_lay

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值