在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}