RxJava2之创建操作符与变换操作符

872 阅读6分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第2天,点击查看活动详情

创建操作符

1.interval

创建一个按固定时间间隔发射整数序列的Observable,相当于定时器。

Observable
    .interval(3, TimeUnit.SECONDS)//指定时间间隔以及时间的单位
    .subscribe(new Consumer<Long>() {
        @Override
        public void accept(Long aLong) throws Exception {
            Log.i(TAG, "accept: "+aLong);
        }
    });

结果为

01-25 14:48:08.920 16172-16199/com.xp.note.rxjava I/RxJavaActivity30: onNext: 31
01-25 14:48:11.919 16172-16199/com.xp.note.rxjava I/RxJavaActivity30: onNext: 32
01-25 14:48:14.920 16172-16199/com.xp.note.rxjava I/RxJavaActivity30: onNext: 33

2.range

创建发射指定范围的整数序列的Observable,类似于for循环,取值范围左闭右开。

Observable
    .range(0,3)
    .subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            Log.i(TAG, "accept: "+integer);
        }
    });

结果为

01-25 14:55:39.341 16711-16711/com.xp.note.rxjava I/RxJavaActivity30: accept: 0
01-25 14:55:40.341 16711-16711/com.xp.note.rxjava I/RxJavaActivity30: accept: 1
01-25 14:55:41.343 16711-16711/com.xp.note.rxjava I/RxJavaActivity30: accept: 2

3.repeat

创建一个n次发射重复数据的Observable

Observable
    .range(0,2)
    .repeat(2)//重复次数
    .subscribe(new Consumer<Integer>() {
        @Override
        public void accept(Integer integer) throws Exception {
            Log.i(TAG, "accept: "+integer);
        }
    });

输出结果

01-25 15:03:50.446 17017-17017/com.xp.note.rxjava I/RxJavaActivity30: accept: 0
01-25 15:03:50.446 17017-17017/com.xp.note.rxjava I/RxJavaActivity30: accept: 1
01-25 15:03:50.446 17017-17017/com.xp.note.rxjava I/RxJavaActivity30: accept: 0
01-25 15:03:50.446 17017-17017/com.xp.note.rxjava I/RxJavaActivity30: accept: 1

变换操作符

变换操作符的作用是对Observable发射的数据按照一定的规则做一些变换操作,然后将变换的数据发射出去。

1.map

map操作符通过指定一个Function对象,将Observable转换为一个新的Observable对象然后发射,观察者将接手新的Observable,然后处理。

Observable.range(0,5).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 {
	        Log.i("TAG", "accept: "+s);
	    }
	});

输出结果

01-29 21:08:25.157 17201-17201/com.xp.note.rxjava I/TAG: accept: 转换之后:0
01-29 21:08:25.158 17201-17201/com.xp.note.rxjava I/TAG: accept: 转换之后:1
01-29 21:08:25.158 17201-17201/com.xp.note.rxjava I/TAG: accept: 转换之后:2
01-29 21:08:25.158 17201-17201/com.xp.note.rxjava I/TAG: accept: 转换之后:3
01-29 21:08:25.158 17201-17201/com.xp.note.rxjava I/TAG: accept: 转换之后:4

2.flatMap(concatMap)

flatMap将一个Observable变换为多个Observables,然后将他们发射的数据放到一个单独的Observable 1167421-7728bea372bd612c.png

 Observable.range(0, 5)
    .flatMap(new Function<Integer, ObservableSource<String>>() {
        @Override
        public ObservableSource<String> apply(Integer integer) throws Exception {
            return Observable.fromArray(integer + "");
        }
    }).subscribe(new Consumer<String>() {
        @Override
        public void accept(String s) throws Exception {
            Log.i("TAG", "accept: " + s);
        }
    });

concatMap和flatMap的功能是一样的, 将一个发射数据的Observable变换为多个Observables,然后将它们发射的数据放进一个单独的Observable。只不过最后合并Observables ,flatMap采用的merge,而concatMap采用的是连接(concat)。总之一句一话,他们的区别在于:concatMap是有序的,flatMap是无序的,concatMap最终输出的顺序与原序列保持一致,而flatMap则不一定,有可能出现交错。

结果输出

01-29 22:43:34.796 29345-29469/com.xp.note.rxjava I/TAG: accept: 0
01-29 22:43:34.796 29345-29469/com.xp.note.rxjava I/TAG: accept: 1
01-29 22:43:34.796 29345-29469/com.xp.note.rxjava I/TAG: accept: 2
01-29 22:43:34.796 29345-29469/com.xp.note.rxjava I/TAG: accept: 3
01-29 22:43:34.796 29345-29469/com.xp.note.rxjava I/TAG: accept: 4

map适用于一对一转换,当然也可以配合flatmap进行适用 flatmap适用于一对多,多对多的场景

flatmap可用于化解循环嵌套,还有一种场景就是连续请求两个接口,第一个接口的返回值是第二个接口的请求参数,在这种情况下,以前我们会在一个请求完成后,在onResponse中获取结果再请求另一个接口。这种接口嵌套,代码看起来是非常丑陋的,运用flatMap就能很好的解决这个问题。代码看起来非常优雅而且逻辑清晰。如果需要保证顺序的话,使用concatMap

更多操作符

3.buffer

buffer将原来的Observable转化为新的Observable,这个新的Observable每次发射一组列表值,而不是一个一个地发射。

aaa8dc.jpg

Observable.range(0, 7)
            .buffer(3)
            .subscribe(new Consumer<List<Integer>>() {//参数是List而不是Integer,说明发射了一组
                @Override
                public void accept(List<Integer> integers) throws Exception {
                    Log.i("TAG", "accept: " + integers.size());
                }
            });

结果输出

04-19 22:00:12.901 11686-11686/com.xp.note.rxjava I/TAG: accept: 3
04-19 22:00:12.902 11686-11686/com.xp.note.rxjava I/TAG: accept: 3
04-19 22:00:12.902 11686-11686/com.xp.note.rxjava I/TAG: accept: 1

4.groupBy

groupBy将原始的Observable拆分成一些Observables集合,这些集合中的每一个都发射原始Observable的一个子序列,哪个数据项由哪一个Observable发射是由一个函数判定的,这个函数给每一项指定一个Key,Key相同的数据会被同一个Observable发射。 iamge

    User user1 = new User("张三丰",100);
    User user2 = new User("张翠山",30);
    User user3 = new User("张无极",18);
    User user4 = new User("珠儿",15);
    User user5 = new User("周芷若",16);
    User user6 = new User("小昭",15);
    User user7 = new User("白眉鹰王",100);

    Observable<GroupedObservable<Integer,User>> obs = Observable.just(user1, user2, user3, user4, user5, user6, user7)
            .groupBy(new Function<User, Integer>() {
        @Override
        public Integer apply(User user) throws Exception {
            return user.getAge();
        }
    });
    Observable.concat(obs).subscribe(new Consumer<User>() {
        @Override
        public void accept(User user) throws Exception {
            Log.i("TAG", "accept: "+user.toString());
        }
    });

结果输出

04-19 22:00:12.950 11686-11686/com.xp.note.rxjava I/TAG: accept: 张三丰 100岁
04-19 22:00:12.951 11686-11686/com.xp.note.rxjava I/TAG: accept: 白眉鹰王 100岁
04-19 22:00:12.953 11686-11686/com.xp.note.rxjava I/TAG: accept: 张翠山 30岁
04-19 22:00:12.953 11686-11686/com.xp.note.rxjava I/TAG: accept: 张无极 18岁
04-19 22:00:12.954 11686-11686/com.xp.note.rxjava I/TAG: accept: 珠儿 15岁
04-19 22:00:12.954 11686-11686/com.xp.note.rxjava I/TAG: accept: 小昭 15岁
04-19 22:00:12.954 11686-11686/com.xp.note.rxjava I/TAG: accept: 周芷若 16岁