Rxjava之变换操作符

Rxjava常见的变化操作符如下:

1.map()变换符

 //转换操作符之map()
        //通过map()操作符对被观察者发送的每一个事件都通过指定的Function对象的apply()方法进行转换处理
        //将之前的事件类型转换成为另外的一种事件类型
        //即通过map()操作符将我们的被观察者发送的事件转换成为任意的类型的事件
        //应用场景:数据类型的转换
        Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
                e.onNext(2);
                e.onNext(3);
                e.onComplete();
            }
        }).map(new Function<Integer, String>() {
            @Override
            public String apply(@NonNull Integer integer) throws Exception {
                //通过apply将事件的类型有integer转换成为了String
                return String.valueOf("通过map()变换操作符将int类型的数据转换成为了String字符串类型的数据 : " + integer.intValue());
            }
        }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "onSubscribe: thread = " + Thread.currentThread().getName());
            }

            @Override
            public void onNext(String s) {
                //最终在onNext中调用得到的是String类型的事件
                Log.d(TAG, "onNext: " + s + "  thread = " + Thread.currentThread().getName());
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "onError: thread = " + Thread.currentThread().getName());
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "onComplete:  thread = " + Thread.currentThread().getName());
            }
        });

打印结果:

2.flatMap()变换操作符

//转换操作符之flatMap()
        //flatMap()操作符的作用是将被观察者发送的事件序列进行拆分 & 单独转换 在合并成为一个新的事件序列最后在进行发送
        //原理:将被观察者发送的事件序列进行拆分成一个个事件 在将每个事件都生成创建一个新的Observable对象
        //每个原始事件都会生成一个新的Observable对象
        //每个拆分的新的事件生成的新的Observable对象最终会汇总到一个新建总的Observable对象中
        //新建的总的Observable对象最终将新合并的事件序列发送给观察者Observer
        //应用场景:无序的将整个被观察者发送的事件序列进行变换

        //注意:新生成的事件序列的顺序是无序的 和旧的事件序列的顺序无关
       Observable.create(new ObservableOnSubscribe<Integer>() {
           @Override
           public void subscribe(ObservableEmitter<Integer> e) throws Exception {
               e.onNext(1);
               e.onNext(2);
               e.onNext(3);
               e.onNext(4);
               e.onComplete();
           }
       }).flatMap(new Function<Integer, ObservableSource<String>>() {
           @Override
           public ObservableSource<String> apply(@NonNull Integer integer) throws Exception {
               ArrayList<String> transforDatas = new ArrayList<>();

               for (int j = 0; j < 3; j++) {
                   Log.d(TAG, "apply: 被观察者的原始事件 " + integer + " 分解成的子事件 " + j + " thread : " + Thread.currentThread().getName());
               }

               return Observable.fromIterable(transforDatas);
           }
       }).subscribe(new Observer<String>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "onSubscribe: thread = " + Thread.currentThread().getName());
            }

            @Override
            public void onNext(String s) {
                Log.d(TAG, "onNext: " + s + "  thread = " + Thread.currentThread().getName());
            }

            @Override
            public void onError(Throwable e) {
                Log.d(TAG, "onError: thread = " + Thread.currentThread().getName());
            }

            @Override
            public void onComplete() {
                Log.d(TAG, "onComplete: thread = " + Thread.currentThread().getName());
            }
        });

打印结果:    

3.concatMap()变换操作符

//转换操作符之concatMap()
        final String[] courseName = {"语文","数学","英语"};
        ArrayList<Student> students = new ArrayList<>();
        for (int j = 0; j < 5; j++) {
            List<Course> courses = new ArrayList<>();
            for (int k = 0; k < 3; k++) {
                courses.add(new Course(courseName[k] + k, (int) (Math.random() * 31 + 70)));
            }
            Student childStudent = new Student("何乐" + j, 22 + j, courses);
            students.add(childStudent);
        }

        Observable.fromIterable(students).subscribe(new Consumer<Student>() {
            @Override
            public void accept(@NonNull Student student) throws Exception {
                List<Course> courses = student.getCourses();
                for (int j = 0; j < courses.size(); j++) {
                    Log.d(TAG, "accept: 学生姓名: " + student.getName() + " 学生年龄 : " + student.getAge() + " 学生学习课程名: " + courses.get(j).getCourseName() + " 学生该门成绩: " + courses.get(j).getScore());
                }
            }
        });

        Log.d(TAG, "------------------------------------------------------------------------------------------------");

        //使用flatMap() / concatMap()直接获取Course对象 不用进行频繁的转换
        //将被观察者发送的原始事件进行拆分 生成一个新的事件序列
        //concatMap()和flatMap()之间的不同点
        //concatMap() 拆分 & 重新合并生成的事件序列的顺序和 旧的的事件序列的顺序是一致的
        //即新生成的事件序列的顺序和严格按照旧的事件序列的顺序来发射
        Observable.fromIterable(students).concatMap(new Function<Student, ObservableSource<Course>>() {
            @Override
            public ObservableSource<Course> apply(@NonNull Student student) throws Exception {
                return Observable.fromIterable(student.getCourses());
            }
        }).subscribe(new Consumer<Course>() {
            @Override
            public void accept(@NonNull Course course) throws Exception {
                Log.d(TAG, "accept: 课程名 " + course.getCourseName() + " 课程成绩 " + course.getScore());
            }
        });

打印结果:

4. switchMap()转换操作符

//转换操作符之switchMap()
        //switchMap()操作符和flatMap()操作符的功能很像,除了一点
         //对于switchMap()每当源Observable发射一个新的数据项,它就取消订阅并停止监视之前的那个数据项
         //变换产生的Observable,并开始监视当前最新发射的这个数据项
         
         //使用测试调度器
         final TestScheduler testScheduler = new TestScheduler();


         Observable.just(10,20,30)
                 .switchMap(new Function<Integer, ObservableSource<Integer>>() {
                     @Override
                     public ObservableSource<Integer> apply(@NonNull Integer integer) throws Exception {
                         int delay = 0;
//                        if(integer == 10){
//                            delay = 100;
//                        }
//
//                        if(integer == 20){
//                            delay = 50;
//                        }
//
//                        if(integer == 30){
//                            delay = 30;
//                        }

                           //生成一个随机产生的延迟值,来延迟变换三个上游发射的三个数据项
                         delay = new Random().nextInt(101);

                        return Observable.fromArray(new Integer[]{integer,integer / 2}).delay(delay,TimeUnit.MILLISECONDS,testScheduler);
                     }
                 }).observeOn(AndroidSchedulers.mainThread())
                 .subscribe(new Consumer<Integer>() {
                     @Override
                     public void accept(@NonNull Integer integer) throws Exception {
                         Log.d(TAG, "accept: " + integer + "  " + Thread.currentThread().getName());
                     }
                 });
            
         //使用测试调度器直接将时间向前推进到1分钟的时间
         testScheduler.advanceTimeBy(1,TimeUnit.MINUTES);

打印项:

 以上SwitchMap代码不管运行多少次打印的结果始终是30 15 不管10 20 30 这三个数据项在switchMap()中变换时生成时间的先后 说明对于switchMap()只要上游源Observable发射了新的数据就会停止订阅和监视之前的旧的数据项的变换产生的Observable,同时会直接订阅监视最新的这个数据项

5. flatMapIterable()转换操作符

//变换操作符之flatMapIterable()
        //flatMapIterable()和flatMap()几乎是一样的,不同的是flatMapIterable()它转化的多个Observable是使用Iterable作为源数据的。
        ArrayList<Integer> list1 = new ArrayList<>();
        ArrayList<Integer> list2 = new ArrayList<>();
        ArrayList<Integer> list3 = new ArrayList<>();

        for(int i = 0;i < 10;i++){
            list1.add(i);
            list2.add(i);
            list3.add(i);
        }

        Observable.just(list1,list2,list3)
                .flatMapIterable(new Function<ArrayList<Integer>, Iterable<Integer>>() {
                    @Override
                    public Iterable<Integer> apply(@NonNull ArrayList<Integer> integers) throws Exception {
                        return integers;
                    }
                }).observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {
                        Log.d(TAG, "accept: " + integer);
                    }
                });

    打印结果:

            

concatMapEager()变换操作符:

//变换操作符之concatMapEager()
        //和flatMap()不同concatMap() concatMapEager()操作符能够保证最终变换生成的数据是有序的
        Observable.just(1,2,3,4,5,6)
                .concatMapEager(new Function<Integer, ObservableSource<String>>() {
                    @Override
                    public ObservableSource<String> apply(@NonNull Integer integer) throws Exception {
                        return Observable.just(String.valueOf(integer));
                    }
                }).subscribe(new Consumer<String>() {
            @Override
            public void accept(@NonNull String s) throws Exception {
                Log.d(TAG, "accept: " + s);
            }
        });

6. buffer()转换操作符:

//转换操作符之buffer()缓冲
        //buffer()变换操作符可以Observable发射的事件序列进行缓冲转换成一个新的Observable对象
        //而且新转换的Observable发射事件时是发射一组列表值而不是一个个发射
        //buffer(count) 每次新生成的Observable事件序列中的事件数量为count个
        Observable.just(1,2,3,4,5).buffer(3).subscribe(new Consumer<List<Integer>>() {
            @Override
            public void accept(@NonNull List<Integer> integers) throws Exception {
                Log.d(TAG, "缓冲区数据");
                for (int j = 0; j < integers.size(); j++) {
                    Log.d(TAG, "accept: " + integers.get(j));
                }
            }
        });

        Log.d(TAG, "--------------------------------------");
        //buffer(count,skip) 每次新转换的Observable事件序列中的事件数量为count
        //并且每次需要跳skip个事件数量的位置重新生成count个事件的新的Observable事件序列
        Observable.just(1,2,3,4,5).buffer(3,2).subscribe(new Consumer<List<Integer>>() {
            @Override
            public void accept(@NonNull List<Integer> integers) throws Exception {
                Log.d(TAG, "缓冲区数据");
                for (int j = 0; j < integers.size(); j++) {
                    Log.d(TAG, "accept: " + integers.get(j));
                }
            }
        });

打印结果:

  

7. scan()操作符:

//Scan()变换操作符
        //Scan操作符对原始Observable发射的第一项数据应用一个函数,
        // 然后将那个函数的结果作为自己的第一项数据发射。它将函数的结果同第二项数据一起填充给这个函数来产生它自己的第二项数据。
        // 它持续进行这个过程来产生剩余的数据序列。这个操作符在某些情况下被叫做accumulator 累加器
        Observable.just(1,2,3,4,5)
                .scan(new BiFunction<Integer, Integer, Integer>() {
                    @Override
                    public Integer apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {
                        Log.d(TAG, "integer : " + integer + "  integer2 : " + integer2);
                        return integer + integer2;
                    }
                }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(@NonNull Integer integer) throws Exception {
                Log.d(TAG, "accept: " + integer);
            }
        });
        Log.d(TAG, "-----------------------------------------------------");
        
        //scan操作符的变体,你可以传递一个种子值给累加器函数的第一次调用(Observable发射的第一项数据)
        // 如果你使用这个版本,scan将发射种子值作为自己的第一项数据。 下游会比源Observable发射的数据项多接收响应一次数据多的就时初始种子值
        Observable.just(1,2,3)
                .scan(10, new BiFunction<Integer, Integer, Integer>() {
                    @Override
                    public Integer apply(@NonNull Integer integer, @NonNull Integer integer2) throws Exception {
                        Log.d(TAG, "intgera : " + integer + "  integerb : " + integer2);
                        return integer + integer2;
                    }
                }).subscribe(new Consumer<Integer>() {
            @Override
            public void accept(@NonNull Integer integer) throws Exception {
                Log.d(TAG, "accept: " + integer);
            }
        });

打印结果:

       

8. groupBy()操作符:

 //变换操作符groupBy()
        //GroupBy操作符将原始Observable分拆为一些Observables集合,
        // 它们中的每一个发射原始Observable数据序列的一个子序列。
        // 哪个数据项由哪一个Observable发射是由一个函数判定的,
        // 这个函数给每一项指定一个Key,Key相同的数据会被同一个Observable发射。
        //RxJava实现了groupBy操作符。它返回Observable的一个特殊子类GroupedObservable,
        //实现了GroupedObservable接口的对象有一个额外的方法getKey,这个Key用于将数据分组到指定的Observable

        //注意:groupBy将原始Observable分解为一个发射多个GroupedObservable的Observable,一旦有订阅,
        //每个GroupedObservable就开始缓存数据。因此,如果你忽略这些GroupedObservable中的任何一个,
        //这个缓存可能形成一个潜在的内存泄露。因此,如果你不想观察,也不要忽略GroupedObservable。
        //你应该使用像take(0)这样会丢弃自己的缓存的操作符。
        //如果你取消订阅一个GroupedObservable,那个Observable将会终止
        //如果之后原始的Observable又发射了一个与这个Observable的Key匹配的数据,groupBy将会为这个Key创建一个新的GroupedObservable。
        //groupBy默认不在任何特定的调度器上执行。
        Observable.range(1,10)
                .groupBy(new Function<Integer, String>() {
                    @Override
                    public String apply(@NonNull Integer integer) throws Exception {
                        return (integer >= 5) ? "大于5" : "小于5";
                    }
                })/*.elementAt(1)*/ //只获取索引为1的那个位置的元素(默认索引从0开始)
                .take(1) //只获取事件序列中的前一个事件和element()是不同的意思
                .subscribe(new Consumer<GroupedObservable<String, Integer>>() {
                    @Override
                    public void accept(@NonNull GroupedObservable<String, Integer> stringIntegerGroupedObservable) throws Exception {
                        String key = stringIntegerGroupedObservable.getKey();
                        Log.d(TAG, "accept: key : " + key + " groupObservable : " + stringIntegerGroupedObservable);

                stringIntegerGroupedObservable
                        .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(@NonNull Integer integer) throws Exception {
                        Log.d(TAG, "accept: " + integer);
                    }
                });
                    }
                }, new Consumer<Throwable>() {
                    @Override
                    public void accept(@NonNull Throwable throwable) throws Exception {
                        Log.d(TAG, "accept: " + throwable.getMessage());
                    }
                });

        //传递一个变换函数,这样它可以在发射结果GroupedObservable之前改变数据项。
        Observable.range(1,10)
                .groupBy(new Function<Integer, String>() {
                    @Override
                    public String apply(@NonNull Integer integer) throws Exception {
                        return integer % 2 == 0 ? "偶数" : "奇数";
                    }
                }, new Function<Integer, String>() {
                    @Override
                    public String apply(@NonNull Integer integer) throws Exception {
                        return String.valueOf(integer + " x");
                    }
                }).subscribe(new Consumer<GroupedObservable<String, String>>() {
            @Override
            public void accept(@NonNull GroupedObservable<String, String> stringStringGroupedObservable) throws Exception {
                Log.d(TAG, "accept: " + stringStringGroupedObservable.getKey());
                if(stringStringGroupedObservable.getKey().equals("奇数")){
                    stringStringGroupedObservable.subscribe(new Consumer<String>() {
                        @Override
                        public void accept(@NonNull String s) throws Exception {
                            Log.d(TAG, "accept: " + s);
                        }
                    });
                }
            }
        });

打印结果:

9. window操作符:

//变换操作符window()
        //window操作符非常类似于buffer操作符,区别在于buffer操作符产生的结果是一个List缓存,
        // 而window操作符产生的结果是一个Observable,订阅者可以对这个结果Observable重新进行订阅处理
        //https://mcxiaoke.gitbooks.io/rxdocs/operators/Window.html
        Observable.range(1,10)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .window(3)
                .subscribe(new Observer<Observable<Integer>>() {
                    @Override
                    public void onSubscribe(@NonNull Disposable d) {
                        Log.d(TAG, "onSubscribe: thread : " + Thread.currentThread().getName());
                    }

                    @Override
                    public void onNext(@NonNull Observable<Integer> integerObservable) {
                        integerObservable.subscribe(new Observer<Integer>() {
                            @Override
                            public void onSubscribe(@NonNull Disposable d) {
                                Log.d(TAG, "onSubscribe: inner   thread : " + Thread.currentThread().getName());
                            }

                            @Override
                            public void onNext(@NonNull Integer integer) {
                                Log.d(TAG, "onNext: inner  : " + integer + "thread : " + Thread.currentThread().getName());
                            }

                            @Override
                            public void onError(@NonNull Throwable e) {
                                Log.d(TAG, "onError: inner thread : " + Thread.currentThread().getName());
                            }

                            @Override
                            public void onComplete() {
                                Log.d(TAG, "onComplete: inner  thread : " + Thread.currentThread().getName());
                            }
                        });
                    }

                    @Override
                    public void onError(@NonNull Throwable e) {
                        Log.d(TAG, "onError: ");
                    }

                    @Override
                    public void onComplete() {
                        Log.d(TAG, "onComplete: ");
                    }
                });

打印结果:

         

以上就是rxjava中常见的变换操作符的介绍

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值