操作符的简单使用

首先说下Rxjava的使用,主要是通过Observable 与SubScriber来进行响应式编程的,Observable通过各种操作符对数据进行操作,然后SubScriber只接收最后处理好的数据。


下边来介绍操作符:


 1、Just操作符


just操作符是用来简化代码的,当你只想要处理onNext方法的时候就可以使用;


Just操作符将某个对象转化为Observable对象,并且将其发射出去,可以使一个数字、一个字符串、数组、Iterate对象等,是一种非常快捷的创建Observable对象的方法,在以后的例子里会大量使用。


Observable.just("这是只关心onNext方法的时候可以直接用函数调用")
                .subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        System.out.println(s);
                    }
                });

2、map操作符,使用map操作符可以转换数据类型,返回你想要处理的类型:


User类是自定义的一个类;


Observable.just("测试操作符map").map(new Func1<String, User>() {

            @Override
            public User call(String s) {
                User user = new User();
                user.setName(s);
                return user;
            }
        }).subscribe(new Subscriber<User>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(User user) {
                System.out.println("user name= " + user.getName());
            }
        });

3、from,他接收的参数可以是数组也可以是集合,作用就是用来分发给订阅者,让订阅者每次只接收一条数据


//from操作符,他接收的参数是可以使是数组跟集合
        String [] ss = {"one","twe","three"};
        Observable.from(ss).subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                System.out.println(s);
            }
        });
        //from操作可以把集合中的数据进行处理,然后让subscribe每次只接收一条
        Observable.create(new Observable.OnSubscribe<List<String>>() {

            @Override
            public void call(Subscriber<? super List<String>> subscriber) {
                List<String> list = new ArrayList<>();
                list.add("aaa");
                list.add("bbb");
                list.add("cccc");
                subscriber.onNext(list);
            }
        }).subscribe(new Action1<List<String>>() {
            @Override
            public void call(List<String> strings) {
                Observable.from(strings).subscribe(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        System.out.println(s);
                    }
                });
            }
        });


4、flatMap操作符,他的作用是返回一个我们想要处理的任意类型的Observable类型的的对象

5、filter操作符,他的作用是用来过滤数据的

6、take操作符,用来限制输出的结果数量,也就是最终Subscriber处理的数据条数。


下边是上边三个操作符的实例:


//flatMap操作符,他的作用是可以返回一个我们想要处理的任意的ObServable类型的对象
        //下边的例子里边我们可以在flatMap中修改以后再返回想要的类型
        Observable.create(new Observable.OnSubscribe<List<String>>() {

            @Override
            public void call(Subscriber<? super List<String>> subscriber) {
                List<String> list = new ArrayList<>();
                list.add("flatMap1");
                list.add("flatMap2");
                list.add("flatMap3");
                list.add("Map4");
                subscriber.onNext(list);
            }
        }).flatMap(new Func1<List<String>, Observable<String>>() {
            @Override
            public Observable<String> call(List<String> strings) {
                return Observable.from(strings);
            }
        }).flatMap(new Func1<String, Observable<String>>() {
            @Override
            public Observable<String> call(String s) {
                if (s.contains("flat"))
                return Observable.create(new Observable.OnSubscribe<String>() {
                    @Override
                    public void call(Subscriber<? super String> subscriber) {
                        subscriber.onNext("正确");
                    }
                });
                return null;
            }
        }).filter(new Func1<String, Boolean>() {//过滤掉
            @Override
            public Boolean call(String s) {
                Log.e("过滤tag",s);
                return s != null;
            }
        }).take(6) //限制输出的结果数量
                .doOnNext(new Action1<String>() {
                    @Override
                    public void call(String s) {
                        Log.e("输出之前做操作tag",s);
                    }
                })
        .subscribe(new Action1<String>() {
            @Override
            public void call(String s) {
                System.out.println(s);
            }
        });


7、subscribeOn操作符:用来指定被观察着运行的线程

8、observeOn操作符:用来指定订阅者要在哪个线程


public static void getAllUserInfo(final UserListAdapter adapter){
        final HttpService service = ServiceFactory.createService(HttpService.class, Canstant.BASEURL);
        service.getUserData().
       subscribeOn(Schedulers.newThread())
                .observeOn(AndroidSchedulers.mainThread()).
                subscribe(new Subscriber<List<User>>() {
                    @Override
                    public void onCompleted() {

                    }

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

                    @Override
                    public void onNext(List<User> users) {
                        adapter.setData(users);
                    }
                });
    }

(具体可以看Demo中的代码,上边只是摘取的)


9、do


 Do操作符就是给Observable的生命周期的各个阶段加上一系列的回调监听,当Observable执行到这个阶段的时候,这些回调就会被触发。在Rxjava实现了很多的doxxx操作符。
    DoOnEach可以给Observable加上这样的样一个回调:Observable每发射一个数据的时候就会触发这个回调,不仅包括onNext还包括onError和onCompleted。
    DoOnNext则只有onNext的时候才会被触发。


 doOnSubscribe和doOnUnSubscribe则会在Subscriber进行订阅和反订阅的时候触发回调。当一个Observable通过OnError或者OnCompleted结束的时候,会反订阅所有的Subscriber。


 DoOnError会在OnError发生的时候触发回调,并将Throwable对象作为参数传进回调函数里;DoOnComplete会在OnCompleted发生的时候触发回调。


DoOnTerminate会在Observable结束前触发回调,无论是正常还是异常终止;finallyDo会在Observable结束后触发回调,无论是正常还是异常终止。


Observable.just("a","b","c").doOnEach(new Action1<Notification<? super String>>() {
        @Override
        public void call(Notification<? super String> notification) {
            System.out.println("notification = " + notification.toString());
        }
    }).doOnNext(new Action1<String>() {
        @Override
        public void call(String s) {
            System.out.println("doOnNext");
        }
    }).doOnCompleted(new Action0() {
        @Override
        public void call() {
            System.out.println("doOnCompleted");
        }
    }).doOnSubscribe(new Action0() {
        @Override
        public void call() {
            System.out.println("doOnSubscribe");
        }
    }).doOnTerminate(new Action0() {
        @Override
        public void call() {
            System.out.println("doOnTerminate");
        }
    })
            .subscribe(new Subscriber<String>() {
                @Override
                public void onCompleted() {
                    System.out.println("onCompleted");
                }

                @Override
                public void onError(Throwable e) {
                    System.out.println("onError");
                }

                @Override
                public void onNext(String s) {
                    System.out.println("onNext");
                }
            });

10、materialize操作符与demeterialize操作符:


 Meterialize操作符将OnNext/OnError/OnComplete都转化为一个Notification对象并按照原来的顺序发射出来,而DeMeterialize则是执行相反的过程。


Observable.just(1,2,3).materialize().subscribe(new Subscriber<Notification<Integer>>() {
            @Override
            public void onCompleted() {
                System.out.println("onCompleted");
            }

            @Override
            public void onError(Throwable e) {
                System.out.println("onError");
            }

            @Override
            public void onNext(Notification<Integer> integerNotification) {
                System.out.println("onNext=" + integerNotification.getValue());
            }
        });
Observable.range(10,10).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println(integer);
            }
        });


<pre name="code" class="java"> //每个1秒发送一个数字TimeUnit.SECONDS是单位,秒
        Observable.interval(1,TimeUnit.SECONDS).map(new Func1<Long, String>() {
            @Override
            public String call(Long aLong) {
                int count = 60;
                return (count - aLong)+ "";
            }
        }).observeOn(AndroidSchedulers.mainThread()).
                subscribe(new Subscriber<String>() {
                    @Override
                    public void onCompleted() {

                    }

                    @Override
                    public void onError(Throwable e) {

                    }

                    @Override
                    public void onNext(String s) {
                        if (s.equals("0")){
                            unsubscribe();
                        }
                        System.out.println("倒计时 interval= " + s);
                    }
                });








13、   Timer 操作符:作用是会在指定时间后发射一个数字0,注意其也是运行在computation Scheduler



Observable.timer(2,TimeUnit.SECONDS).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Long>() {
            @Override
            public void call(Long aLong) {
                System.out.println("timer = " + aLong);
            }
        });






14、buffer操作符:



他有俩种使用的方式,一种是通过时间来控制,一种是通过限制skip的值



//buffer操作符,如果是传入这么多参数的话会按buffer里边的参数(如果传的是一个整体,那么是整体输出),每隔3个数字发射出前俩个数字
        Observable.just(1,2,3,4,5,6,7,8,9,10).buffer(2,3).subscribe(new Action1<List<Integer>>() {
            @Override
            public void call(List<Integer> integers) {
                System.out.println(integers.toString());
            }
        });
        //每隔3秒输出2-4个数字,用interval数字是从0开始一直累加的
        Observable.interval(1,TimeUnit.SECONDS).buffer(3,TimeUnit.SECONDS).
                observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<List<Long>>() {
            @Override
            public void call(List<Long> longs) {
                System.out.println(longs.toString());
            }
        });

15、scan操作符 :

Scan操作符对一个序列的数据应用一个函数,并将这个函数的结果发射出去作为下个数据应用这个函数时候的第一个参数使用,有点类似于递归操作



//scan对集合中的数据进行遍历
        Observable.from(list).scan(new Func2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer integer, Integer integer2) {
                return integer *integer2;
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("相乘的结果是= " + integer);
            }
        });






16、distinctUntilChanged 与distinct操作符:前边一个是连续去重,也就是如果有几个连续的数,或是对象等是相同的,那么就只留一个,而distinct是去重,只要有相同的就去重。


User user = new User();
        user.setName("jack");
        User user1 = new User();
        user1.setName("jack111");
        Observable.just(user,user,user,user1,user,user1,user).distinctUntilChanged().subscribe(new Action1<User>() {
            @Override
            public void call(User user) {
                    System.out.println("distinctUntilChanged = "+user.getName());
            }
        });
        Observable.just(user,user,user,user1,user,user1,user).distinct().subscribe(new Action1<User>() {
            @Override
            public void call(User user) {
                System.out.println("distinct = " + user.getName());
            }
        });



先介绍这么多吧。慢慢补充!


测试的Demo:可以看下:


17、debounce



debounce操作符对源Observable每产生一个结果后,如果在规定的间隔时间内没有别的结果产生,则把这个结果提交给订阅者处理,否则忽略该结果。

值得注意的是,如果源Observable产生的最后一个结果后在规定的时间间隔内调用了onCompleted,那么通过debounce操作符也会把这个结果提交给订阅者。

Observable.create(new Observable.OnSubscribe<Integer>() {
            @Override
            public void call(Subscriber<? super Integer> subscriber) {
                if(subscriber.isUnsubscribed()) return;
                try {
                    //产生结果的间隔时间分别为100、200、300...900毫秒
                    for (int i = 1; i < 10; i++) {
                        subscriber.onNext(i);
                        Thread.sleep(i * 100);
                    }
                    subscriber.onCompleted();
                }catch(Exception e){
                    subscriber.onError(e);
                }
            }
        }).subscribeOn(Schedulers.newThread())
          .debounce(400, TimeUnit.MILLISECONDS)  //超时时间为400毫秒
          .subscribe(
                new Action1<Integer>() {
                    @Override
                    public void call(Integer integer) {
                        System.out.println("Next:" + integer);
                    }
                }, new Action1<Throwable>() {
                    @Override
                    public void call(Throwable throwable) {
                        System.out.println("Error:" + throwable.getMessage());
                    }
                }, new Action0() {
                    @Override
                    public void call() {
                        System.out.println("completed!");
                    }
                });



18、SwitchMap:



switchMap操作符与flatMap操作符类似,都是把Observable产生的结果转换成多个Observable,然后把这多个Observable“扁平化”成一个Observable,并依次提交产生的结果给订阅者。

与flatMap操作符不同的是,switchMap操作符会保存最新的Observable产生的结果而舍弃旧的结果,举个例子来说,比如源Observable产生A、B、C三个结果,通过switchMap的自定义映射规则,映射后应该会产生A1、A2、B1、B2、C1、C2,但是在产生B2的同时,C1已经产生了,这样最后的结果就变成A1、A2、B1、C1、C2,B2被舍弃掉了!

Observable.just(10, 20, 30).switchMap(new Func1<Integer, Observable<Integer>>() {
            @Override
            public Observable<Integer> call(Integer integer) {
                //10的延迟执行时间为200毫秒、20和30的延迟执行时间为180毫秒
                int delay = 200;
                if (integer > 10)
                    delay = 180;

                return Observable.from(new Integer[]{integer, integer / 2}).delay(delay, TimeUnit.MILLISECONDS);
            }
        }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
            @Override
            public void call(Integer integer) {
                System.out.println("switchMap Next:" + integer);
            }
        });

上边俩个结合使用最常见的功能就是EditTextView的联想功能,一个控制隔多长时间没有输入,一个控制只接收最近返回的Observer结果。