RxJava之条件和布尔操作符

本文详细介绍了RxJava中用于处理条件和布尔操作的一系列操作符,如all、amb、contains、exists、isEmpty、defaultIfEmpty、sequenceEqual、skipUntil、skipWhile、takeUntil和takeWhile。通过示例代码和Log打印,展示了这些操作符如何根据条件过滤、判断和选择Observable发射的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在RxJava中,条件和布尔操作符作用于Observable中数据源,比如数据源中的数据是否满足某种条件,或者 数据源是否为空,又或者数据源为空时如何发射备份数据。在过滤操作符 曾了解take、skip操作符的使用,我们是否为它们设定一定的执行的条件呢?

all

流程图

这里写图片描述

概述

all操作符判定原Observable发射的所有数据是否全部满足满足某个条件。

all操作符接收一个函数参数,创建并返回一个单布尔值的Observable,如果原Observable正常终止并且每一项数据都满足条件,就返回true;如果原Observable的任何一项数据不满足条件或者非正常终止就返回False。

all操作符默认不在任何特定的调度器上执行。

API

Javadoc: all(Func1)

示例代码

Observable.from(getListOfStudent())
        .subscribeOn(Schedulers.io())
        .all(new Func1<Student, Boolean>() {
            @Override
            public Boolean call(Student student) {
                return student.getAge() > 16 && stutdent.getAge() < 40;
            }
        }).observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<Boolean>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Boolean aBoolean) {
                Log.i(TAG, "all(): " + aBoolean);

            }
        });

Log打印

all(): true

示例解析

示例中,对Observable发射的每一个数据,即Student对象,通过all操作符来判定每个Student对象的成员变量age是否在16至40之间,此时all操作符创建并一个单布尔值的Observabl。细看Log打印,观察者订阅后,收到一个Boolean数据,其值为true,表明原Observable可以正常终止,而且发射的每一项数据都满足需求条件。

amb

流程图

这里写图片描述

概述

amb操作符对于给定两个或多个Observables,它只发射首先发射数据或通知的那个Observable的所有数据。

当你传递多个Observable给amb操作符时,该操作符只发射其中一个Observable的数据和通知:首先发送通知给amb操作符的的那个Observable,不管发射的是一项数据还是一个onError或onCompleted通知,amb将忽略和丢弃其它所有Observables的发射物。

RxJava的实现是amb操作符时,有一个类似的对象方法ambWith。例如,Observable.amb(o1,o2)和o1.ambWith(o2)是等价的。

该操作符操作符默认不在任何特定的调度器上执行。

API

Javadoc: amb(T o1, T ... o2)(可接受2到9个参数)

示例代码

Observable.amb(Observable.just(new Student(1001, "amb - 1", 20)).delay(2, TimeUnit.SECONDS),
                                Observable.just(new Student(1002, "amb - 2", 21)))
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                mAdaStudent.addData(student);
                Log.i(TAG, student.toString());
            }
        });

Log打印

Student{id='1002'name='amb - 2', age=21}

示例解析

从示例代码中,传递给amb操作符两个Observable,但是第一个Observable通过delay操作符,将其延迟2S发射数据,而第二个未做延迟处理。因此,amb操作符首先收到的是第二个Observable发射的数据。从amb概述中可知,amb操作符将丢弃第一个Observable中的数据,只发射第二个的数据。从Log打印 中,可以看出只打印了与第二个Observable相对应的数据,意味着观察者只接收到了第二个Observable中的数据,恰恰印证了amb操作符的作用。

contains

流程图

这里写图片描述

概述

contains操作符将接收一个特定的值作为一个参数,判定原Observable是否发射该值,若已发射,则创建并返回的Observable将发射true,否则发射false。

contains操作符默认不在任何特定的调度器上执行。

API

Javadoc: contains(Object)

示例代码

Observable.from(getListOfStudent())
        .subscribeOn(Schedulers.io())
        .contains(new Student(2, "B", 33))
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<Boolean>() {
            @Override
            public void call(Boolean aBoolean) {
                Log.i(TAG, "contains:" + aBoolean);
            }
        });

public class Student extends Id {
    private String name;
    private int age;

    ***

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        Student student = (Student) o;

        return age == student.age;

    }

    ****
}

private List<Student> getListOfStudent() {
    List<Student> list = new ArrayList<>();
    list.add(new Student(1, "A", 23));
    list.add(new Student(2, "B", 33));
    list.add(new Student(3, "C", 24));
    list.add(new Student(4, "D", 24));
    list.add(new Student(5, "E", 36));
    list.add(new Student(6, "F", 23));
    return list;
}

Log打印

contains:true

示例解析

先看Student类,该类重写了equals方法,并设定age属性作为判定两个Student对象是否相同的标准。接下来看contains操作符,接收到了一个Student对象且age属性的值为33.在Observable的发射的数据中,第二个数据的age属性值为33,与coantains操作符接受参数对象的age属性值一致,故在Log打印为contains:true。若在Observable的发射的数据中,没有数据的age属性值为33,此时Log应打印为contains:false.

exists

流程图

这里写图片描述

概述

exists操作符类似与contains操作符,不同的是,其接受一个函数参数,在函数中,对原Observable发射的数据,设定比对条件并做判断。若任何一项满足条件就创建并返回一个发射true的Observable,否则返回一个发射false的Observable。

该操作符默认不在任何特定的调度器上执行。

API

Javadoc: exists(Func1))

示例代码

Observable.from(getListOfStudent())
        .subscribeOn(Schedulers.io())
        .exists(new Func1<Student, Boolean>() {
            @Override
            public Boolean call(Student student) {
                return student.getAge() == 33;
            }
        }).observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<Boolean>() {
            @Override
            public void call(Boolean aBoolean) {
                Log.i(TAG, "exists:" + aBoolean);
            }
        });

Log打印

exists:true

isEmpty

流程图

这里写图片描述

概述

isEmpty操作符用于判定原始Observable是否没有发射任何数据。若原Observable未发射任何数据,创建创建并返回一个发射true的Observable,否则返回一个发射false的Observable。

isEmpty操作符默认不在任何特定的调度器上执行。

API

Javadoc: isEmpty()

示例代码

Observable.from(new ArrayList<Student>())
        .subscribeOn(Schedulers.io())
        .isEmpty()
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<Boolean>() {
            @Override
            public void call(Boolean aBoolean) {
                Log.i(TAG, "isEmpty:" + aBoolean);
            }
        });

Log打印

isEmpty:true

示例解析

示例代码中,通过Observable.from()创建了一个Observable,其数据源是一个ArrayList但其是空的,意味着Observable不会发射任何一条数据。此时,调用isEmpty操作符,应创建并返回一个发射true的Observable,观察订阅后应接收此Observable。具体结果如何,见Log打印。

defaultIfEmpty

流程图

这里写图片描述

概述

defaultIfEmpty操作接受一个备用数据,在原Observable没有发射任何数据正常终止(以onCompletedd的形式),该操作符以备用数据创建一个Observable并将数据发射出去。

RxJava将这个操作符实现为defaultIfEmpty。它默认不在任何特定的调度器上执行。

API

Javadoc: defaultIfEmpty(T)

示例代码

Observable.from(new ArrayList<Student>())
        .subscribeOn(Schedulers.io())
        .defaultIfEmpty(new Student(1001, "default - 1", 20))
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Action1<Student>() {
            @Override
            public void call(Student student) {
                mAdaStudent.addData(student);
                Log.i(TAG, student.toString());
            }
        });

Log打印

Student{id='1001'name='default - 1', age=20}

sequenceEqual

流程图

这里写图片描述

概述

sequenceEqual操作符接受传递两个Observable参数,它会比较两个Observable发射的数据,如果发射数据的序列是相同的(相同的数据,相同的顺序,相同的终止状态),创建创建并返回一个发射true的Observable,否则返回一个发射false的Observable。

这里写图片描述
sequenceEqual(Observable,Observable,Func2)变体接收两个Observable参数和一个函数参数,在函数参数中,可以比较两个参数是否相同。

该操作符默认不在任何特定的调度器上执行。

API

Javadoc: sequenceEqual(Observable,Observable)
Javadoc: sequenceEqual(Observable,Observable,Func2)

示例代码

Observable.sequenceEqual(Observable.from(getListOfStudent()), 
                         Observable.from(getListOfStudent()).delay(1, TimeUnit.SECONDS))
            .subscribeOn(Schedulers.io())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Action1<Boolean>() {
                @Override
                public void call(Boolean aBoolean) {
                    Log.i(TAG, "SequenceEqual:" + aBoolean);
                }
            });

Log打印

SequenceEqual:true

skipUntil

流程图

这里写图片描述

概述

skipUntil操作符在观察者订阅原Observable时,该操作符将是忽略原Observable的发射的数据,直到第二个Observable发射了一项数据那一刻,它才 开始发射原Observable发射的数据。

该操作符默认不在任何特定的调度器上执行。

API

Javadoc: skipUntil(Observable))

示例代码

Observable.interval(1, TimeUnit.SECONDS)
    .subscribeOn(Schedulers.io())
    .skipUntil(Observable.just(1).delay(3, TimeUnit.SECONDS))
    .flatMap(new Func1<Long, Observable<Student>>() {
        @Override
        public Observable<Student> call(Long aLong) {
            return Observable.just(new Student(aLong.intValue(), "skipUntil - " + aLong.intValue(), aLong.intValue() + 20));
        }
    }).observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Subscriber<Student>() {
        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(Student student) {
            Log.i(TAG, student.toString());
            mAdaStudent.addData(student);
            if (student.getId() >  5) {
                unsubscribe();
            }
        }
    });

Log打印

Student{id='2'name='skipWhile - 2', age=22} 
Student{id='3'name='skipWhile - 3', age=23} 
Student{id='4'name='skipWhile - 4', age=24} 
Student{id='5'name='skipWhile - 5', age=25} 
Student{id='6'name='skipWhile - 6', age=26} 

skipWhile

流程图

这里写图片描述

概述

skipWhile操作符丢弃原Observable发射的数据,直到发射的数据不满足一个指定的条件,才开始发射原Observable发射的数据。

在观察者订阅原Observable时,skipWhile操作符将忽略原Observable的发射物,直到你指定的某个条件变为false时,它开始发射原Observable发射的数据。

skipWhile操作符默认不在任何特定的调度器上执行。

API

Javadoc: skipWhile(Func1)

示例代码

Observable.interval(1, TimeUnit.SECONDS)
        .subscribeOn(Schedulers.io())
        .skipWhile(new Func1<Long, Boolean>() {
            @Override
            public Boolean call(Long aLong) {
                return aLong < 2;
            }
        })
        .flatMap(new Func1<Long, Observable<Student>>() {
            @Override
            public Observable<Student> call(Long aLong) {
                return Observable.just(new Student(aLong.intValue(), "skipWhile - " + aLong.intValue(), aLong.intValue() + 20));
            }
        }).observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                Log.i(TAG, student.toString());
                mAdaStudent.addData(student);
                if (student.getId() > 5) {
                    unsubscribe();
                }
            }
        });

Log打印

Student{id='2'name='skipWhile - 2', age=22} 
Student{id='3'name='skipWhile - 3', age=23} 
Student{id='4'name='skipWhile - 4', age=24} 
Student{id='5'name='skipWhile - 5', age=25} 
Student{id='6'name='skipWhile - 6', age=26} 

takeUntil

流程图

这里写图片描述

概述

takeUntil操作符与skipUntil操作符作用相反,当第二个Observable发射了一项数据或者终止时,丢弃原Observable发射的任何数据。

在RxJava中有很多takeUntil操作符的变体,以满足各种情况下的需求。下面一一描述:
这里写图片描述
takeUntil(Observable)变体接受一个Observable参数,暂命名为_observable,在观察者订阅原Observable时,takeUntil操作符监视_observable。如果observable发射了一项数据或者发射了一个终止通知(onError通知或nCompleted通知),takeUntil操作符创建并返回的Observable会停止发射原Observable发射的数据并终止。
这里写图片描述
takeUntil(Func1)变体接受一个函数参数,不在RxJava 1.0.0版中,其行为类始于takeWhile(Func1)。

takeUntil操作符默认不在任何特定的调度器上执行。

API

Javadoc: takeUntil(Observable)

Javadoc: takeUntil(Func1)

示例代码

Observable.interval(1, TimeUnit.SECONDS)
    .subscribeOn(Schedulers.io())
    .takeUntil(Observable.just(1).delay(3, TimeUnit.SECONDS))
    .flatMap(new Func1<Long, Observable<Student>>() {
        @Override
        public Observable<Student> call(Long aLong) {
            return Observable.just(new Student(aLong.intValue(), "takeUntil - " + aLong.intValue(), aLong.intValue() + 20));
        }
    }).observeOn(AndroidSchedulers.mainThread())
    .subscribe(new Subscriber<Student>() {
        @Override
        public void onCompleted() {

        }

        @Override
        public void onError(Throwable e) {

        }

        @Override
        public void onNext(Student student) {
            Log.i(TAG, student.toString());
            mAdaStudent.addData(student);
        }
    });

Log打印

Student{id='0'name='takeUntil - 0', age=20}
Student{id='1'name='takeUntil - 1', age=21}

takeWhile

流程图

这里写图片描述

概述

takeWhile操作符与skipWhile操作符作用相反。在观察者订阅原Observable时,takeWhile创建并返回原Oservable的镜像Observable,暂命名为_observable,发射原Observable发射的数据。当你指定的某个条件变为false时,_observable发射onCompleted终止通知。

takeWhile操作符默认不在任何特定的调度器上执行。

API

Javadoc: takeWhile(Func1)

示例代码

Observable.interval(1, TimeUnit.SECONDS)
        .subscribeOn(Schedulers.io())
        .takeWhile(new Func1<Long, Boolean>() {
            @Override
            public Boolean call(Long aLong) {
                return aLong < 3;
            }
        })
        .flatMap(new Func1<Long, Observable<Student>>() {
            @Override
            public Observable<Student> call(Long aLong) {
                return Observable.just(new Student(aLong.intValue(), "takeWhile - " + aLong.intValue(), aLong.intValue() + 20));
            }
        }).observeOn(AndroidSchedulers.mainThread())
        .subscribe(new Subscriber<Student>() {
            @Override
            public void onCompleted() {

            }

            @Override
            public void onError(Throwable e) {

            }

            @Override
            public void onNext(Student student) {
                Log.i(TAG, student.toString());
                mAdaStudent.addData(student);
            }
        });

Log打印

Student{id='0'name='takeWhile - 0', age=20} 
Student{id='1'name='takeWhile - 1', age=21} 
Student{id='2'name='takeWhile - 2', age=22} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值