RxJava- 操作符之一

涉及到列表的数据时,总是会想到一个过滤这个词语。比如,在1-100的整数中,筛选出偶数或者奇数相加,或者将前49个数相加,又或者后36个数相加,等等。在这样的场景中,不由想到将需要的数据筛选出来。在发射的Observable中,可不可以做筛选呢?

过滤序列 - filter

filter操作符是对源Observable产生的结果按照指定条件进行过滤,只有满足条件的结果才会提交给订阅者。

其流程图如下:

    Observable.from(mLists)
            .filter(new Func1<Student, Boolean>() {
                @Override
                public Boolean call(Student student) {
                    return student.getName().startsWith("A");
                }
            })
            .subscribe(new Observer<Student>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(Student student) {
                    mAdaStu.addData(student);
                }
            });

查看上述代码,传一个新的Func1对象给filter()函数,即只有一个参数的函数。Func1有一个AppInfo对象来作为它的参数类型并且返回Boolean对象。只要条件符合filter()函数就会返回true。此时,值会发射出去并且所有的观察者都会接收到。

因为该方法只有一个回调方法,我们可以使用java8的的lumbda表达式,形式如下:

    Observable.from(mLists)
        .filter(student -> student.getName().startsWith("A"))
        .subscribe(new Observer<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                mAdaStu.addData(student);
            }
        });

filter()函数最常用的用法之一时过滤null对象,它帮我们免去了在onNext()函数调用中再去检测null值,让我们把注意力集中在应用业务逻辑上.。

    .filter(new Func1<AppInfo,Boolean>(){
        @Override
        public Boolean call(AppInfo appInfo){
            return appInfo != null;
        }
    })

截取前N个 - take

take操作符是用整数N来作为一个参数,把源Observable产生的结果,提取前面的N个提交给订阅者,而忽略后面的结果。

其流程图如下

示例代码:

    Observable.from(mLists)
        .take(5)
        .subscribe(new Observer<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                mAdaStu.addData(student);
            }
        });

从结果图例中可以看到,对这个可观测序列应用take(3)函数,然后我们创建一个只发射可观测源的第一个到第五个数据的列,将序列发射出去并且观察者都会接收到。

截取后N个 -  takeLast

takeLast操作符是把源Observable产生的结果的后n项提交给订阅者,提交时机是Observable发布onCompleted通知之时。

其流程图如下:

示例代码:

    Observable.from(mLists)
        .takeLast(5)
        .subscribe(new Observer<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                mAdaStu.addData(student);
            }
        });

从结果图例中可以看到,对这个可观测序列应用take(3)函数,然后我们创建一个只发射可观测源的最后5个数据的新序列, 将序列发射出去并且观察者都会接收到。

截取某条件后第一个 - takeFirst

takeFirst操作符类似于take操作符,同时也类似于first操作符,都是获取源Observable产生的结果列表中符合指定条件的前一个或多个,与first操作符不同的是,first操作符如果获取不到数据,则会抛出NoSuchElementException异常,而takeFirst则会返回一个空的Observable,该Observable只有onCompleted通知而没有onNext发送Observable。

takeFirst操作符的流程图如下:

示例代码:

    Observable.from(mLists)
            .takeFirst(new Func1<Student, Boolean>() {
                @Override
                public Boolean call(Student student) {
                    return student.getName().startsWith("B");
                }
            })
            .subscribe(new Observer<Student>() {
                @Override
                public void onCompleted() {
                    Log.i("123", "doTakeFirst - onCompleted");
                }

                @Override
                public void onError(Throwable e) {
                    Log.i("123", "doTakeFirst - onError");
                }

                @Override
                public void onNext(Student student) {
                    Log.i("123", "doTakeFirst - onNext");
                    mAdaStu.addData(student);
                }
            });   

过滤重复源 - distinct

distinct操作符对源Observable产生的结果进行过滤,把重复的结果过滤掉,只输出不重复的结果给订阅者。

distinct操作符的流程图如下:

用之前学过的take()和repeat()创建一个重复发射的列表。

    Observable<AppInfo> fullOfDuplicates = Observable.from(apps)
    .take(3)
    .repeat(3);

从上述代码可知,fullOfDuplicates变量里把List的前三个重复了3次,有9个并且许多重复的,然后使用distinct进行过滤。

    fullOfDuplicates.distinct()
        .subscribe(new Observer<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                mAdaStu.addData(student);
            }
        });

观看上面的效果图,很明显,观察者只是收到了三个不重复的Observable,重复的Observable已被distinct函数过滤

与前一个Observable某一条件重复过滤 - distinctUntilChanged

distinctUntilChanged操作符对源Observable产生的结果进行条件过滤,把与前一个Observable某条件重复的结果过滤掉,只输出不重复的结果给订阅者。

distinctUntilChanged操作符的流程图如下:

示例代码:

    Observable.from(mLists)
        .distinctUntilChanged(new Func1<Student, String>() {
            @Override
            public String call(Student student) {
                return student.getAge();
            }
        })
        .subscribe(new Observer<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                mAdaStu.addData(student);
            }
        });

依据上述代码及效果图,明显的看出来,观察者收到的都是与前一个Observable的age字段不重复的Observable,与前一个Observable的age字段

重复的Observable已被distinctUntilChanged过滤掉。

只发射一个元素 - first

first操作符是从Observable列表中只发射第一个,将其余的都过滤掉,同时观察者也只收到第一个Observable。如果不做条件限制,默认列表中的第一个,否则第一个Observable为条件限制的第一个。

first操作符的流程图如下:

示例代码:

  Observable.from(mLists)
        .first()
        .subscribe(new Observer<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                mAdaStu.addData(student);
            }
        });

当然,first与其他操作符一样,可以传func()参数,对Observable列表中的哪一个是第一个进行限制。例如,学生列表中,将名字第一个字母为"B"作为

第一个Observable,我们可以这样写:

    .first(new Func1<Student, Boolean>() {
                    @Override
                    public Boolean call(Student student) {
                        return student.getName().startsWith("B");
                    }
                })
    //Lamada写法
    .first(student -> student.getName().startsWith("B"))

效果图

只发射一个元素 - last

last操作符,与first操作符恰恰相反,是从Observable列表中只发射最后一个,将其余的都过滤掉,同时观察者也只收到最后一个Observable。

last操作符的流程图如下:

示例代码:

    Observable.from(mLists)
        .last()
        .subscribe(new Observer<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                mAdaStu.addData(student);
            }
        });

不发射前N个 - skip

skip操作符与take相对应,是以N作为参数,表示从Observable列表中忽略前N个,将其余的全部发射,同时观察者也只收到发射的Observable。

skip操作符的流程图如下:

示例代码:

    Observable.from(mLists)
        .skip(2)
        .subscribe(new Observer<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                mAdaStu.addData(student);
            }
        });

不发射后N个 - skipLast

skipLast操作符与takeLast相对应,是以N作为参数,表示从Observable列表中忽略后N个,将其余的全部发射,同时观察者也只收到发射的Observable。

skipLast操作符的流程图如下:

示例代码:

    Observable.from(mLists)
            .skipLast(6)
            .subscribe(new Observer<Student>() {
                @Override
                public void onCompleted() {

                }

                @Override
                public void onError(Throwable e) {

                }

                @Override
                public void onNext(Student student) {
                    mAdaStu.addData(student);
                }
            });   

发射某一位置 - elementAt

elementAt操作符以N作为参数,从Observable列表中发射位置在N处的元素,将其余的忽略,同时观察者也只收到发射的Observable。

elementAt操作符的流程图如下:

示例代码:

    Observable.from(mLists)
        .elementAt(2)
        .subscribe(new Observer<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                mAdaStu.addData(student);
            }
        });

注:亲测N不在序列表范围内,如果N为负数,会报异常IndexOutOfBoundsException;如果N大于列表长度,不会报异常,但观察者不会收到Observable。

间隔一段时间发射 - sample

sample操作符是Observable将会在间隔一段时间内发送最后一个。sample()支持全部的时间单位:秒,毫秒,天,分等等。sample主要用于动态变化的Observable列表,

比如温度传感器,它每秒都会发射当前室内的温度。在发射时,可以设置时间间隔。在Observable后面加一个sample(),我们将创建一个新的可观测序列,它将在一个

指定的时间间隔里由Observable发射最近一次的数值,如果我们想让它定时发射第一个元    素而不是最近的一个元素,我们可以使用throttleFirst()。

sample操作符的流程图如下:

示例代码:

    Observable<Integer> sensor = [...]

    sensor.sample(30,TimeUnit.SECONDS)
        .subscribe(new Observer<Integer>() {

            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Integer currentTemperature) {
                updateDisplay(currentTemperature)
            }
        });

超时 - timeout

timeout操作符主要检测间隔一段事件发射一个Observable,使用timeout()函数来监听源可观测序列,就是在我们设定的时间间隔内如果没有得到一个值则发射一个错误,即onError()方法。

timeout操作符的流程图如下:

示例代码:

    Subscription subscription = getCurrentTemperature()
    .timeout(2,TimeUnit.SECONDS)
    .subscribe(new Observer<Integer>() {

        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {
            Log.d("RXJAVA","You should go check the sensor, dude");
        }

        @Override
        public void onNext(Integer currentTemperature) {
            updateDisplay(currentTemperature)
        }
    });

发射频率过快 - debounce

debounce操作符过滤掉由Observable发射的速率过快的数据;如果在一个指定的时间间隔过去了仍旧没有发射一个,那么它将发射最后的那个。

debounce操作符的流程图如下:

时间: 2024-08-29 19:56:32

RxJava- 操作符之一的相关文章

RxJava操作符总结之过滤

RxJava操作符总结之过滤 jsut() just(T t1, T t2, T t3 ....) ,just能够传入多个同样类型的參数,并将当前參数一个接着一个的发送. Observable.just("1","2","3") .subscribe(new Action1<String>() { @Override public void call(String s) { System.out.println(s); } }); 1

RxJava操作符——条件和布尔操作符(Conditional and Boolean Operators)

RxJava系列教程: 1. RxJava使用介绍 [视频教程] 2. RxJava操作符 ? Creating Observables(Observable的创建操作符) [视频教程] ? Transforming Observables(Observable的转换操作符) [视频教程] ? Filtering Observables(Observable的过滤操作符) [视频教程] ? Combining Observables(Observable的组合操作符) [视频教程] ? Erro

RxJava操作符(03-变换操作)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51649975 本文出自:[openXu的博客] 目录: Buffer FlatMap flatMapIterable concatMap switchMap GroupBy Map cast Scan Window 源码下载 ??变换操作符的作用是对Observable发射的数据按照一定规则做一些变换操作,然后将变换后的数据发射出去,接下来看看RxJava中主要有哪些变换操作符: 1. B

RxJava操作符 -创建型

操作符类型 创建操作 变换操作 过滤操作 组合操作 错误处理 辅助操作 条件和布尔操作 算术和聚合操作 连接操作 转换操作 创建操作 create 你可以使用create操作符从头开始创建一个Observable,给这个操作符传递一个接受观察者作为参数的函数,编写这个函数让它的行为表现为一个Observable–恰当的调用观察者的onNext,onError和onCompleted方法. 一个形式正确的有限Observable必须尝试调用观察者的onCompleted正好一次或者它的onErro

Android RxJava操作符一览

前言 把现在接触到的操作符全部整理进来,方便查阅,遇到新的也会添加进来.和RxJavaLearn 的README.md同步更新. 操作符决策树 直接创建一个Observable(创建操作) 组合多个Observable(组合操作) 对Observable发射的数据执行变换操作(变换操作) 从Observable发射的数据中取特定的值(过滤操作) 转发Observable的部分值(条件/布尔/过滤操作) 对Observable发射的数据序列求值(算术/聚合操作) 创建操作 用于创建Observab

RxJava操作符(二) __变换操作

RxJava变换操作符 这周真心比较累,一直都在加班,今天才有点自己的时间来学习新的内容,外包工作苦啊! 上周学习了各种创建操作符,像create,from,Just,Defer-.等等,这周中也工作中也用了不少,有时间也需要总结一下自己在工作中使用的操作符.好了,现在来开始学习一个变换操作符吧,不知道什么意思没关系,一个一个去试错吧. map 官方的翻译是对于Observable发射的每一项数据,都会应用一个函数,执行变换操作,然后返回一个发射这些结果的Observable. 还是举个例子吧,

RxJava操作符(05-结合操作)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51656736 本文出自:[openXu的博客] 目录: CombineLatest Join Merge StartWith Switch Zip 源码下载 结合操作就是将多个Observable发射的数据按照一定规则组合后发射出去,接下来看看RxJava中的结合操作符: 1. CombineLatest ??当两个Observables中的任何一个发射数据时,使用一个函数结合每个Obse

RxJava操作符repeatWhen()和retryWhen()

第一次见到.repeatWhen()和.retryWhen()这两个操作符的时候就非常困惑了.不得不说,它们绝对是"最令人困惑弹珠图"的有力角逐者. 然而它们都是非常有用的操作符:允许你有条件的重新订阅已经结束的Observable.我最近研究了它们的工作原理,现在我希望尝试着去解释它们(因为,我也是耗费了一些精力才参透它们). Repeat与Retry的对比 首先,来了解一下.repeat()和.retry()之间最直观的区别是什么?这个问题并不难:区别就在于什么样的终止事件会触发重

RxJava操作符(04-过滤操作)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51656494 本文出自:[openXu的博客] 目录: Debounce Distinct ElementAt Filter First Last IgnoreElements SampleThrottleFirst SkipSkipLast TakeTakeLast 源码下载 "过滤操作",顾名思义,就是过滤掉Observable发射的一些数据,不让他发射出去,也就是忽略丢弃掉

RxJava操作符(02-创建操作)

转载请标明出处: http://blog.csdn.net/xmxkf/article/details/51645348 本文出自:[openXu的博客] 目录: Create Defer EmptyNeverThrow From Interval Just Range Repeat Timer 源码下载 ??在上一篇博客中我们初步体验了Rxjava的使用,领略了RxJava对于异步操作流编码的简洁风格,接下来的一系列博客,我们主要学习RxJava中的操作符,也就是RxJava的一些API,由于