Rxjava的组合操作符和过滤操作符

  • Rxjava的组合操作符
  • 组合操作符的作用
  • 组合多个被观察者
  • 1. concat()/concatArray()
  • 2. merge()/mergeArray()
  • 3. concatDelayError()/mergeDelayError()
  • 合并多个事件
  • 1. zip()
  • 2. combineLatest()
  • 3. combineLatestDelayError()
  • 4. reduce()
  • 5. collect()
  • 发送事件前追加发送事件
  • 1. startWith()/startWithArray()
  • 统计发送事件的数量
  • 1. count()
  • Rxjava的过滤操作符
  • 根据指定事件条件来过滤事件
  • 1. filter()
  • 2. ofType()
  • skip()和skipLast()
  • distinct()/distinctUntilChanged()
  • 根据指定事件数量过滤事件
  • 1. take()
  • 2. takeLast()
  • 根据指定时间过滤事件
  • 1. throttleFirst()/throttleLast()
  • 2. Sample()
  • 3. throttleWithTimeout () / debounce()
  • 根据指定事件位置过滤事件
  • 1. firstElement()/lastElement()
  • 2. elementAt()
  • 3. elementAtOrError()


Rxjava的组合操作符

组合操作符的作用

创建被观察者对象发送事件

组合多个被观察者

1. concat()/concatArray()

  • 作用:将多个被观察者组合在一个发送数据,合并后按顺序串行执行
  • 两者的区别:concat()组合被观察者数量≤4个,而concatArray()则可>4个

原理图:

rxswift操作符 rxjava的操作符_android

代码示例:

Observable.concat(Observable.just(1, 2, 3),
                Observable.just("z", "x", "c")
        ).subscribe(new Observer() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "onSubscribe: ");
            }

            @Override
            public void onNext(Object value) {

                Log.d(TAG, "onNext: "+value);
            }

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

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

2. merge()/mergeArray()

  • 作用:将多个被观察者组合在一起发送数据,合并后按时间线并行执行
  • 两者的区别:merge()组合被观察者数量≤4个,而mergeArray()则可>4个
  • merge()为时间并行执行,而concat()是按照发送顺序串行执行

原理图:

rxswift操作符 rxjava的操作符_java_02

代码示例:

Observable.concat( Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS), // 从0开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
                Observable.intervalRange(2, 3, 1, 1, TimeUnit.SECONDS) // 从2开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
        ).subscribe(new Observer<Long>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "onSubscribe: ");
            }

            @Override
            public void onNext(Long value) {

                Log.d(TAG, "onNext: "+value);
            }

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

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

rxswift操作符 rxjava的操作符_rxswift操作符_03

3. concatDelayError()/mergeDelayError()

  • 作用:在concat和merge的相关方法中,如果其中一个被观察者发送了Error事件,那么就会停止发送事件。如果我们想把所有的正常事件都发送完成之后再发送Error事件的话,我们就可以使用mergeArrayDelayError()和concatArrayDelayError()

代码示例:

不使用concatDelayError()的情况:

Observable.concat(
                Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                        emitter.onNext(1);
                        emitter.onNext(2);
                        emitter.onNext(3);
                        emitter.onError(new NullPointerException()); // 发送Error事件,因为无使用concatDelayError,所以第2个Observable将不会发送事件 emitter.onComplete();
                    }
                }),

                Observable.just(4, 5, 6))
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer value) {

                        Log.d(TAG, "onNext: " + value);
                    }

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

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

rxswift操作符 rxjava的操作符_rxswift操作符_04

使用concatDelayError():

Observable.concatArrayDelayError(
                Observable.create(new ObservableOnSubscribe<Integer>() {
                    @Override
                    public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
                        emitter.onNext(1);
                        emitter.onNext(2);
                        emitter.onNext(3);
                        emitter.onError(new NullPointerException()); // 发送Error事件,因为无使用concatDelayError,所以第2个Observable将不会发送事件 emitter.onComplete();
                    }
                }),

                Observable.just(4, 5, 6))
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer value) {

                        Log.d(TAG, "onNext: " + value);
                    }

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

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

rxswift操作符 rxjava的操作符_rxswift操作符_05

合并多个事件

1. zip()

  • 作用:合并两个Observable发射的事件,根据BiFunction函数生成一个新的值发射出去。当其中一个Observable发送数据结束或者出现异常后,另一个Observable也将停止发送数据。也就是说正常情况下,发送的数据长度会与两个Observable中最少事件的数量一样。

代码示例:

Observable.zip(
                Observable.just("a", "b", "c"),
                Observable.just(1, 2, 3),
                new BiFunction<String, Integer, String>() {

                    @Override
                    public String apply(String s, Integer integer) throws Exception {
                        return s + integer;
                    }
                }).subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(String value) {

                        Log.d(TAG, "onNext: " + value);
                    }

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

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

rxswift操作符 rxjava的操作符_rxswift操作符_06

2. combineLatest()

  • 作用:当两个Observables中的任何一个发送了数据后,将先发送了数据的Observables 的最后一个数据 与 另外一个Observable发送的每个数据结合,最终基于该函数的结果发送数据。
  • 与Zip()的区别:Zip() = 按个数合并,即1对1合并;CombineLatest() = 按时间合并,即在同一个时间点上合并。

代码示例如下:

Observable.combineLatest(
                Observable.just("a", "b", "c"),
                Observable.intervalRange(0, 3, 1, 1, TimeUnit.SECONDS), // 第2个发送数据事件的Observable:从0开始发送、共发送3个数据、第1次事件延迟发送时间 = 1s、间隔时间 = 1s
                new BiFunction<String, Long, String>() {

                    @Override
                    public String apply(String s, Long l) throws Exception {
                        return s + l;
                    }
                }).subscribe(new Observer<String>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(String value) {

                        Log.d(TAG, "onNext: " + value);
                    }

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

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z86vLdgV-

rxswift操作符 rxjava的操作符_android_07

3. combineLatestDelayError()

  • 作用类似于concatDelayError() / mergeDelayError()

4. reduce()

  • 把被观察者需要发送的事件聚合成1个事件发送
  • 聚合的逻辑要求自己撰写,但是本质就是前两个数据聚合然后与后一个数据继续进行聚合,以此类推。

具体使用: 1+2+3+4+5

Observable.just(1,2,3,4,5).reduce(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 {
                Log.d("TAG", "accept: "+integer);
            }
        });

rxswift操作符 rxjava的操作符_rxswift操作符_08

5. collect()

  • 将被观察者Observable发送的数据事件收集到一个数据结构里。

代码示例:

Observable.just("1","2","3","2")
                .collect(new Callable<List<Integer>>() { //创建数据结构
                    @Override
                    public List<Integer> call() throws Exception {
                        return new ArrayList<Integer>();
                    }
                }, new BiConsumer<List<Integer>, String>() {//收集器
                    @Override
                    public void accept(List<Integer> integers, String s) throws Exception {
                        integers.add(Integer.valueOf(s));
                    }
                }).subscribe(new Consumer<List<Integer>>() {
            		@Override
            		public void accept(List<Integer> integers) throws Exception {
                		Log.e("---",integers+"");
            		}
        		});

发送事件前追加发送事件

1. startWith()/startWithArray()

  • 作用:在一个被观察者发送事件前,追加发送一些数据/或者一个新的被观察者
  • 区别:startWith’()为追加一个数据,startWithArray()为追加多个数据
Observable.just(1, 2, 3)
                .startWith(0)  // 追加单个数据 = startWith()
                .startWithArray(1, 2, 3) // 追加多个数据 = startWithArray()
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "onNext: " + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

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


        Observable.just(1, 2, 3).
                startWith(Observable.just(4, 5, 6)).
                subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer value) {
                        Log.d(TAG, "onNext: " + value);
                    }

                    @Override
                    public void onError(Throwable e) {
                    }

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

统计发送事件的数量

1. count()

  • 统计被观察者发送事件的数量

代码示例:

Observable.just(1, 2, 3)
                .count()
                .subscribe(new Consumer<Long>() {
                    @Override
                    public void accept(Long aLong) throws Exception {
                        Log.e(TAG, "发送的事件数量 =  " + aLong);

                    }
                });

rxswift操作符 rxjava的操作符_java_09

Rxjava的过滤操作符

  • 作用:Rxjava的过滤操作符常用来筛选/过滤被观察者发送的事件也可以说是观察者接收的事件。

根据指定事件条件来过滤事件

1. filter()

  • 作用:通过一定逻辑来过滤被观察者发送的事件,如果返回true则发送事件,否则不会发送。
  • 应用场景:筛选符合要求的事件。

原理图:

rxswift操作符 rxjava的操作符_数据_10

代码示例:发送1—5中对三取余为1的数字

Observable.just(1,2,3,4,5).filter(new Predicate<Integer>() {
            @Override
            public boolean test(Integer integer) throws Exception {
                return integer % 3 == 1;
            }
        }).subscribe(new Observer<Integer>() {
            @Override
            public void onSubscribe(Disposable d) {
                Log.d(TAG, "onSubscribe: ");
            }

            @Override
            public void onNext(Integer integer) {
                Log.d(TAG, "onNext: "+integer);
            }

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

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

2. ofType()

  • 作用:ofType()是filter操作符的一个特殊形式,他过滤一个被观察者只返回指定类型的数据。比如说发送1和”1“,就可以过滤String类型或者Integer类型。

原理图:

rxswift操作符 rxjava的操作符_ide_11

具体使用:

Observable.just(1, 2, "hello", "world")
                .ofType(Integer.class)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext: " + integer);
                    }

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

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

skip()和skipLast()

  • skip()作用:忽略Observable发射的前n项数据,只保留之后的数据。
  • skipLast()作用:从结尾往前数跳过指定数量的事件。
  • 区别就是一个跳前面一个跳后面。

原理图:

rxswift操作符 rxjava的操作符_ide_12

代码示例:

Observable.just(1, 2, 3,4)
                .skip(2)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext: " + integer);
                    }

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

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



Observable.just(1, 2, 3,4)
                .skipLast(2)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext: " + integer);
                    }

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

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

distinct()/distinctUntilChanged()

  • 作用:过滤被观察者发送事件序列中的重复的事件。
  • 区别是:distinct()方法过滤重复的事件,而distinctUntilChanged()过滤连续重复的事件。

原理图:

rxswift操作符 rxjava的操作符_ide_13

rxswift操作符 rxjava的操作符_android_14

具体使用:

// 使用1:过滤事件序列中重复的事件
        Observable.just(1, 2, 3,4,1,2,1)
                .distinct()
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext: " + integer);
                    }

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

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


        //使用2:过滤事件序列中 连续重复的事件
        // 下面序列中,连续重复的事件 = 3、4
        Observable.just(1,2,3,1,2,3,3,4,4 )
                .distinctUntilChanged()
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext: " + integer);
                    }

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

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

rxswift操作符 rxjava的操作符_rxswift操作符_15

根据指定事件数量过滤事件

需求场景:通过设置指定的事件数量,仅发送特定数量的事件

1. take()

  • 作用:只发送前面的N项数据

原理图:

rxswift操作符 rxjava的操作符_java_16

代码示例:

Observable.just(1, 2, 3,4,1,2,1)
                .take(4)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext: " + integer);
                    }

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

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

2. takeLast()

  • 作用:发射被观察者后面的N项数据

原理图:

rxswift操作符 rxjava的操作符_数据_17

代码示例:

Observable.just(1, 2, 3,4,1,2,1)
                .takeLast(2)
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext: " + integer);
                    }

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

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

根据指定时间过滤事件

1. throttleFirst()/throttleLast()

  • 作用:在某段时间内,只发送该段时间内的第一次时间/最后一次事件。比如在一段时间内连续点击按钮,但是只执行第一次的点击操作。

原理图:

rxswift操作符 rxjava的操作符_java_18

具体使用:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
                Thread.sleep(500);
                e.onNext(2);
                Thread.sleep(400);
                e.onNext(3);
                Thread.sleep(300);
                e.onNext(4);
                Thread.sleep(300);
                e.onNext(5);
                Thread.sleep(300);
                e.onNext(6);
                Thread.sleep(400);
                e.onNext(7);
                Thread.sleep(300);
                e.onNext(8);
                Thread.sleep(300);
                e.onNext(9);
                Thread.sleep(300);
                e.onComplete();

            }
        }).throttleFirst(1, TimeUnit.SECONDS)//每1秒中采用数据
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext: " + integer);
                    }

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

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

rxswift操作符 rxjava的操作符_java_19

以上代码若采用throttleLast(),则发送得事件是3,6,9。

2. Sample()

  • 作用:在某段时间内,只发送该段时间内最新(最后)1次事件
  • 和throttleLast() 操作符类似,仅需要把上文的 throttleLast() 改成Sample()操作符即可

3. throttleWithTimeout () / debounce()

  • 作用:发送数据事件时,若两次发送事件的间隔小于指定时间,就会丢弃前一次的数据,直到指定时间内都没有新数据发射时才会发送后一次的数据。

原理图:

rxswift操作符 rxjava的操作符_rxswift操作符_20

代码示例:

Observable.create(new ObservableOnSubscribe<Integer>() {
            @Override
            public void subscribe(ObservableEmitter<Integer> e) throws Exception {
                e.onNext(1);
                Thread.sleep(500);
                e.onNext(2);
                Thread.sleep(1011);
                e.onNext(3);
                Thread.sleep(300);
                e.onNext(4);
                Thread.sleep(600);
                e.onNext(5);
                Thread.sleep(1200);
                e.onNext(6);
                Thread.sleep(400);
                e.onNext(7);
                Thread.sleep(300);
                e.onNext(8);
                Thread.sleep(300);
                e.onNext(9);
                Thread.sleep(300);
                e.onComplete();

            }
        }).throttleWithTimeout(1, TimeUnit.SECONDS)//每1秒中采用数据
                .subscribe(new Observer<Integer>() {
                    @Override
                    public void onSubscribe(Disposable d) {
                        Log.d(TAG, "onSubscribe: ");
                    }

                    @Override
                    public void onNext(Integer integer) {
                        Log.d(TAG, "onNext: " + integer);
                    }

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

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

rxswift操作符 rxjava的操作符_android_21

根据指定事件位置过滤事件

1. firstElement()/lastElement()

  • 作用:仅选取第一个元素/最后一个元素

具体使用:

Observable.just(1, 2, 3, 4, 5)
                .firstElement()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "获取到的第一个事件是: " + integer);
                    }
                });

        Observable.just(1, 2, 3, 4, 5)
                .lastElement()
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "获取到的第一个事件是: " + integer);
                    }
                });

rxswift操作符 rxjava的操作符_android_22

2. elementAt()

  • 作用:指定接收某个元素(通过索引值确定)
  • 允许越界,即获取的位置索引>发送事件的序列长度

代码示例:

Observable.just(1, 2, 3, 4, 5)
                .elementAt(2)
                .subscribe(new Consumer<Integer>() {
                    @Override
                    public void accept(Integer integer) throws Exception {
                        Log.d(TAG, "获取到的第一个事件是: " + integer);
                    }
                });

3. elementAtOrError()

  • 在elementAt()的基础上,当出现越界情况时抛出异常