RxJava2极速入门——Rxjava操作符详解之条件布尔操作符
RxJava操作符——条件布尔操作符
最近公司人事变动太大,工作比较忙,会尽量保持一周一更,以下正文开始:
Conditional and Boolean Operators:Operators that evaluate one or more Observables or items emitted by Observables
条件布尔操作常用用于对Observable的一些条件判断,或者对Observable元数据进行一些过滤操作;
常见分类如下:
All
all:determine whether all items emitted by an Observable meet some criteria
all作用判断Observable是否所有的发射都满足某一个条件
原理图如下:
示例代码以及源码如下
private fun operatorsAll() =
Observable.range(1, 4).all {
it < 5 }.subscribe(getBaseSingleObserver("operatorsAll"))
/**
* 运行结果如下:
* com.ypz.rxjavademo I/operatorsAll: onSubscribe
* com.ypz.rxjavademo I/operatorsAll: onNext:value-true
* 相关源码如下
* */
/**
* Returns a Single that emits a Boolean that indicates whether all of the items emitted by the source
* ObservableSource satisfy a condition.
*
* @param predicate
* a function that evaluates an item and returns a Boolean
* @return a Single that emits {@code true} if all items emitted by the source ObservableSource satisfy the
* predicate; otherwise, {@code false}
*/
@CheckReturnValue
@SchedulerSupport(SchedulerSupport.NONE)
public final Single<Boolean> all(Predicate<? super T> predicate) {
ObjectHelper.requireNonNull(predicate, "predicate is null");
return RxJavaPlugins.onAssembly(new ObservableAllSingle<T>(this, predicate));
}
/**
* A functional interface (callback) that returns true or false for the given input value.
* @param <T> the first value
*/
public interface Predicate<T> {
/**
* Test the given input value and return a boolean.
* @param t the value
* @return the boolean result
* @throws Exception on error
*/
boolean test(@NonNull T t) throws Exception;
}
public final class ObservableAllSingle<T> extends Single<Boolean> implements FuseToObservable<Boolean> {
//省略部分源码。。。。。。。
@Override
public Observable<Boolean> fuseToObservable() {
return RxJavaPlugins.onAssembly(new ObservableAll<T>(source, predicate));
}
static final class AllObserver<T> implements Observer<T>, Disposable {
@Override
public void onNext(T t) {
if (done) {
return;
}
boolean b;
try {
b = predicate.test(t);
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
upstream.dispose();
onError(e);
return;
}
if (!b) {
done = true;
upstream.dispose();
downstream.onSuccess(false);
}
}
}
}
结合代码可以得到:
- all 结束运算的时候会返回 Boolean
- 当然当运行异常的时候还是会产生Error事件,建议使用SingleObsever< Boolean >避免一些不必要的运行异常
- all的核心接口是Predicate的实现,通过AllObserver中onNext的实现反复调用Predicate然后返回运算结果
Amb
Amb:given two or more source Observables, emit all of the items from only the first of these Observables to emit an item or notification
Amb作用判断两个或多个Observable的发射问题:当有一个Observable最先开始发射事件时,则取该Observable其余Observable则丢弃。
原理图如下:
示例代码以及源码如下
private fun operatorsAmb() {
Observable.amb(mutableListOf(
Observable.just(1).delay(1, TimeUnit.SECONDS),
Observable.just(5)
)).subscribe(getBaseObsever("operatorsAmb"))
}
/**
* 运行结果如下:
* com.ypz.rxjavademo I/operatorsAmb: onSubscribe
* com.ypz.rxjavademo I/operatorsAmb: onNextValue:5
* 相关源码:
* */
/**
* Mirrors the one ObservableSource in an Iterable of several ObservableSources that first either emits an item or sends
* a termination notification.
*
* @param <T> the common element type
* @param sources
* an Iterable of ObservableSource sources competing to react first. A subscription to each source will
* occur in the same order as in the Iterable.
* @return an Observable that emits the same sequence as whichever of the source ObservableSources first
* emitted an item or sent a termination notification
*/
@CheckReturnValue
@NonNull
@SchedulerSupport(SchedulerSupport.NONE)
public static <T> Observable<T> amb(Iterable<? extends ObservableSource<? extends T>> sources) {
ObjectHelper.requireNonNull(sources, "sources is null");
return RxJavaPlugins.onAssembly(new ObservableAmb<T>(null, sources));
}
public final class ObservableAmb<T> extends Observable<T> {
final ObservableSource<? extends T>[] sources;
final Iterable<? extends ObservableSource<? extends T>> sourcesIterable;
public ObservableAmb(ObservableSource<? extends T>[] sources, Iterable<? extends ObservableSource<? extends T>> sourcesIterable) {
this.sources = sources;
this.sourcesIterable = sourcesIterable;
}
@Override
@SuppressWarnings("unchecked")
public void subscribeActual(Observer<? super T> observer) {
ObservableSource<? extends T>[] sources = this.sources;
int count = 0;
if (sources == null) {
sources = new Observable[8];
try {
for (ObservableSource<? extends T> p : sourcesIterable) {
if (p == null) {
EmptyDisposable.error(new NullPointerException("One of the sources is null"), observer);
return;
}
if (count == sources.length) {
ObservableSource<? extends T>[] b = new ObservableSource[count + (count >> 2)];
System.arraycopy(sources, 0, b, 0, count);
sources = b;
}
sources[count++] = p;
}
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
EmptyDisposable.error(e, observer);
return;
}
} else {
count = sources.length;
}
if (count == 0) {
EmptyDisposable.complete(observer);
return;
} else
if (count == 1) {
sources[0].subscribe(observer);
return;
}
AmbCoordinator<T> ac = new AmbCoordinator<T>(observer, count);
ac.subscribe(sources