Android框架源码分析——RxJava过滤操作符

一、简介:前面几篇已经介绍了关于RxJAva的创建、转换、功能等操作符,接下来本篇一起看看剩下的条件过滤的操作符

二、过滤操作符的作用:

过滤 / 筛选 被观察者(Observable)发送的事件 & 观察者 (Observer)接收的事件

三、过滤操作符的分类

Android框架源码分析——RxJava过滤操作符_第1张图片

四、操作符介绍

 

  • filter()

 

  1. 作用:根据条件过滤发送的事件,符合条件的才会发送
  2. 参数:Predicate 对象 当返回true时,事件才会分送,若返回false则忽略此次发送
  3. 使用示例
   Observable.just(1, 2, 3,4,5)
                .filter(new Predicate() {
                    @Override
                    public boolean test(Integer integer) throws Exception {
                        return integer <= 3; // 此处为判断条件返回true则发送事件
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Log.e("=====", o + "");
                    }
                });.filter(new Predicate() {
                    @Override
                    public boolean test(Integer integer) throws Exception {
                        return integer <= 3; // 此处为判断条件返回true则发送事件
                    }
                })
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Log.e("=====", o + "");
                    }
                });

输出结果:

05-06 11:13:32.250 15316-15316/com.example.administrator.googleplay E/=====: 1
05-06 11:13:32.250 15316-15316/com.example.administrator.googleplay E/=====: 2
05-06 11:13:32.250 15316-15316/com.example.administrator.googleplay E/=====: 3
  • offType () 

 

  1. 作用根据发送数据的类型过滤
  2. 参数: 字节码 文件 .class 表示允许输出的数据类型
  3. 使用示例
Observable.just(1, "A", 3,"C",5)
                .ofType(Integer.class) 
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Log.e("=====", o + "");
                    }
                }); .ofType(Integer.class) 
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Log.e("=====", o + "");
                    }
                });

输出结果:

05-06 11:18:40.943 15316-15316/com.example.administrator.googleplay E/=====: 1
05-06 11:18:40.944 15316-15316/com.example.administrator.googleplay E/=====: 3
05-06 11:18:40.944 15316-15316/com.example.administrator.googleplay E/=====: 5

输出结果均为Integer类型,String类型的数据被过滤掉了

 

  • skip()/ skipLast()

 

  1. 作用:跳过一定数量的事件再发送
  2. 参数:integer 表示跳过的个数
  3. 重载
//参数: time 跳过的时间、 TimeUnit 时间单位
skip(long time, TimeUnit unit)
//参数: time 跳过的时间、 TimeUnit 时间单位 、Scheduler  调度器
skip(long time, TimeUnit unit, Scheduler scheduler)

    4、使用示例

 Observable.just(1, "A", 3,"C",5)
                //表述跳过的个数
                .skip(2)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Log.e("=====", o + "");
                    }
                }); .skip(2)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Log.e("=====", o + "");
                    }
                });

输出结果:

05-06 11:27:39.211 15316-15316/com.example.administrator.googleplay E/=====: 3
05-06 11:27:39.211 15316-15316/com.example.administrator.googleplay E/=====: C
05-06 11:27:39.211 15316-15316/com.example.administrator.googleplay E/=====: 5

5、skip 重载和 skipLast 的使用示例

Observable.intervalRange(0,7,0,1,TimeUnit.SECONDS)
                .skip(2,TimeUnit.SECONDS) //跳过前两秒的事件
                .skipLast(2)//跳过最后两个数据
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Log.e("=====", o + "");
                    }
                });.skip(2,TimeUnit.SECONDS) //跳过前两秒的事件
                .skipLast(2)//跳过最后两个数据
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Log.e("=====", o + "");
                    }
                });

输出结果:

05-06 11:31:36.040 15316-15316/com.example.administrator.googleplay E/=====: 2
05-06 11:31:37.040 15316-15316/com.example.administrator.googleplay E/=====: 3
05-06 11:31:38.038 15316-15316/com.example.administrator.googleplay E/=====: 4

从0开始输出7个数 即0——6,过滤前两秒数据0和1,提过最后两个数据5和6,输出之间的数据2,3,4;

 

  • distinct() / distinctUntilChanged()

 

  1. 作用:对发送事件中重复的数据进行过滤
  2. distinct() 使用示例
  Observable.just(1,2,4,3,3,4,4,5,5,5)
                .distinct()
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("=====", integer + "");
                    }
                });.distinct()
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("=====", integer + "");
                    }
                });

输出结果:

05-06 11:41:41.712 16360-16360/com.example.administrator.googleplay E/=====: 1
05-06 11:41:41.712 16360-16360/com.example.administrator.googleplay E/=====: 2
05-06 11:41:41.712 16360-16360/com.example.administrator.googleplay E/=====: 4
05-06 11:41:41.712 16360-16360/com.example.administrator.googleplay E/=====: 3
05-06 11:41:41.713 16360-16360/com.example.administrator.googleplay E/=====: 5

对上述发送的事件中重复的2,3,4,5都只输出了一个,过滤掉其他的

   3、distinctUntilChanged() 只过滤连续重复的显示第一个

 Observable.just(1,2,4,3,3,4,4,5,5,5)
                .distinctUntilChanged()
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("=====", integer + "");
                    }
                });.distinctUntilChanged()
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("=====", integer + "");
                    }
                });

输出结果:

05-06 11:44:28.338 16360-16360/com.example.administrator.googleplay E/=====: 1
05-06 11:44:28.338 16360-16360/com.example.administrator.googleplay E/=====: 2
05-06 11:44:28.338 16360-16360/com.example.administrator.googleplay E/=====: 4
05-06 11:44:28.338 16360-16360/com.example.administrator.googleplay E/=====: 3
05-06 11:44:28.338 16360-16360/com.example.administrator.googleplay E/=====: 4
05-06 11:44:28.338 16360-16360/com.example.administrator.googleplay E/=====: 5

这次的输出比之前多输出一个4,是因为第一个4虽然和后面的重复但不是连续重复,所以会被输出,其他连续的只输出第一个

 

  • take() 和 takeLast()  

 

  1. 作用:限定发送事件的数量
  2. 参数 :integer  限定的数量
  3. 二者比较:take()正序输出 限定的数量 takeLast() 输出倒数数量的事件
  4. 使用示例
Observable.just(1,2,4,3,3)
                .takeLast(3)
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("=====", integer + "");
                    }
                }); .takeLast(3)
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.e("=====", integer + "");
                    }
                });

输出结果:

05-06 11:51:23.571 16360-16360/com.example.administrator.googleplay E/=====: 4
05-06 11:51:23.571 16360-16360/com.example.administrator.googleplay E/=====: 3
05-06 11:51:23.571 16360-16360/com.example.administrator.googleplay E/=====: 3
  • throttleFirst()/ throttleLast()

 

  1. 作用:限定时间内只发送第一次/最后一次的事件
  2. 参数:time  设定的时间  TimeUntil  时间单位
  3. 使用示例:
Observable.intervalRange(0,7,0,1,TimeUnit.SECONDS)
                .throttleFirst(2,TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Log.e("=====", o + "");
                    }
                });.throttleFirst(2,TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Log.e("=====", o + "");
                    }
                });

输出结果:

05-06 11:56:03.752 17153-17153/com.example.administrator.googleplay E/=====: 0
05-06 11:56:06.734 17153-17153/com.example.administrator.googleplay E/=====: 3
05-06 11:56:09.734 17153-17153/com.example.administrator.googleplay E/=====: 6
  • throttleWithTimeout () / debounce()

 

  1. 作用:发送数据事件时,若2次发送事件的间隔<指定时间,就会丢弃前一次的数据,直到指定时间内都没有新数据发射时才会发送后一次的数据
  2. 使用示例
 Observable.create(new ObservableOnSubscribe() {
            @Override
            public void subscribe(ObservableEmitter e) throws Exception {
                e.onNext(1); // 发送事件1
                Thread.sleep(500);
                e.onNext(2); // 发送事件2 间隔500 ms  事件1会被 2 替代
                Thread.sleep(1500); //间隔1500 ms  事件2 被发送
                e.onNext(3); // 发送事件3
                Thread.sleep(500);
                e.onNext(4); // 发送事件4  间隔500 ms  事件3会被 4替代
                Thread.sleep(500);
                e.onNext(5); // 发送事件5  间隔500 ms  事件4会被 5替代  并输出5
            }
        }).throttleWithTimeout(1,TimeUnit.SECONDS)
                .subscribeOn(Schedulers.io())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Consumer() {
                    @Override
                    public void accept(Object o) throws Exception {
                        Log.e("=====", o + "");
                    }
                });

按代码中注释分析,输出的结果应该为2,5 ,运行程序输出结果:

05-06 13:14:25.902 18509-18509/com.example.administrator.googleplay E/=====: 2
05-06 13:14:28.406 18509-18509/com.example.administrator.googleplay E/=====: 5
  • firstElement / lastElement 

 

  1. 作用:仅选取第1个元素 / 最后一个元素
  2. 使用示例
// 获取第1个元素
        Observable.just(1, 2, 3, 4, 5)
                  .firstElement()
                  .subscribe(new Consumer() {
                     @Override
                    public void accept( Integer integer) throws Exception {
                        Log.d("====="+ integer);
                    }
                });
 

// 获取最后1个元素 Observable.just(1, 2, 3, 4, 5) .lastElement() .subscribe(new Consumer() { @Override public void accept( Integer integer) throws Exception { Log.d("====="+ integer); } });输出

05-06 13:14:25.902 18509-18509/com.example.administrator.googleplay E/=====: 1
05-06 13:14:28.406 18509-18509/com.example.administrator.googleplay E/=====: 5
  • elementAt()/ elementAtOrError()

 

  1. 作用:只获取指定位置的事件发送
  2. 参数: index  获取参数的下标 从0开始
  3. 重载 index 获取参数的下标 从0开始, Object   默认值,如果下标越界则返回默认值
  4. 使用示例
   Observable.just(1, 2, 3, 4, 5)
                  .elementAt(2)
                  .subscribe(new Consumer() {
                      @Override
                      public void accept( Integer integer) throws Exception {
                          Log.d("====="+ integer);
                      }
        });

获取的位置索引 > 发送事件序列长度时,设置默认参数
        Observable.just(1, 2, 3, 4, 5)
                .elementAt(6,10)
                .subscribe(new Consumer() {
                    @Override
                    public void accept( Integer integer) throws Exception {
                      Log.d("====="+ integer);
                    }
                });

输出结果:

05-06 13:14:25.902 18509-18509/com.example.administrator.googleplay E/=====: 3
05-06 13:14:28.406 18509-18509/com.example.administrator.googleplay E/=====: 10

对于elementAtOrError()作用和elementAt()一样,不允许下标越界,若下标越界则会抛出异常

以上是RxJava的过滤操作符的使用简介,这些操作方法在开发过程中对业务逻辑的处理起着重要的作用。

你可能感兴趣的:(Android框架源码分析——RxJava过滤操作符)