map—— 一对一转换,一般是转换成结果,如string到int的转换。可以集合进行转换,每次转换都接着执行onNext操作。
看个map的例子
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("hello world");
}
}).map(new Function<String, Integer>() {
@Override
public Integer apply(String s) throws Exception {
return s.hashCode();
}
})
.subscribe(new io.reactivex.Observer<Integer>() {
@Override
public void onSubscribe(Disposable disposable) {
}
@Override
public void onNext(Integer number) {
Log.d("RXJava2", "hascode: " + number);
}
@Override
public void onError(Throwable throwable) {
}
@Override
public void onComplete() {
}
});
我们多次强调所有的订阅者关系都会是形如observable.subscribe(observer)。那么从上面的例子中,肯定可以看到经过调用map方法之后,仍然返回Observable具体实例,当然,参考线程变换一文,经过map之后,肯定是经过装饰者模式进行了一层Observeable组合包装,经过suscibe方法之后,也进行了一层Observer组合包装。
具体情况不再详细分析,可以详细看线程变换一文,原理大体一致。现在主要大概分析下经过map之后,返回的ObservableMap如何执行subscribe方法:
public final class ObservableMap<T, U> extends AbstractObservableWithUpstream<T, U> {
final Function<? super T, ? extends U> function;
public ObservableMap(ObservableSource<T> source, Function<? super T, ? extends U> function) {
super(source);
this.function = function;
}
@Override
public void subscribeActual(Observer<? super U> t) {
source.subscribe(new MapObserver<T, U>(t, function));
}
static final class MapObserver<T, U> extends BasicFuseableObserver<T, U> {
final Function<? super T, ? extends U> mapper;
MapObserver(Observer<? super U> actual, Function<? super T, ? extends U> mapper) {
super(actual);
this.mapper = mapper;
}
@Override
public void onNext(T t) {
if (done) {
return;
}
if (sourceMode != NONE) {
actual.onNext(null);
return;
}
U v;
try {
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
actual.onNext(v);
}
@Override
public int requestFusion(int mode) {
return transitiveBoundaryFusion(mode);
}
@Override
public U poll() throws Exception {
T t = qs.poll();
return t != null ? ObjectHelper.<U>requireNonNull(mapper.apply(t), "The mapper function returned a null value.") : null;
}
}
}
我们可以看到,直接调用source.subscribe(new MapObserver<T, U>(t, function)),进而进入到MapObserver的onNexy方法中,主要看下面几句代码:
try {
v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
} catch (Throwable ex) {
fail(ex);
return;
}
actual.onNext(v);
执行mapper.apply(t),这里mapper即为map方法参数,获得值v,本例中即为s.hashCode, 接着执行事件发射,到达最基层observer,打印log。
flatmap—— 一对多转换,多对多转换,每次转换都会生成observable,而且是全部转换完成才提交给订阅者处理。
flatmap的作用一般是用于一个列表做扁平化处理,比如一个学生数据结构的表单,想对这个表单里的单元数据做一一处理,那么flatmap就派上场用到了。flatmap的实现方式仍然和前面分析的大致。不过既然是从一对多转换,我们先得出一个的就是肯定通过某个组合包装的Observable,在subscribe订阅的时候通过循环往外发射数据,而observer观察者也应该通过循环接收数据。
我们以一个例子以及进入相关的关键代码来分析是否与猜想的一致:
observable.just(studentList).flatMap(new Func1<List, Observable<?>>() {
@Override
public Observable<?> call(List list) {
return Observable.fromInterable(list);
}
}).subscribe(new Action1<Object>() {
@Override
public void call(Object o) {
Log.d("flatmap", o.toString());
}
});
上面的例子中,studentList是一个list列表。那么经过flatMap方法
public final <R> Observable<R> flatMap(Function<? super T, ? extends ObservableSource<? extends R>> mapper, boolean delayErrors, int maxConcurrency, int bufferSize) {
ObjectHelper.requireNonNull(mapper, "mapper is null");
ObjectHelper.verifyPositive(maxConcurrency, "maxConcurrency");
ObjectHelper.verifyPositive(bufferSize, "bufferSize");
if (this instanceof ScalarCallable) {
T v = ((ScalarCallable)this).call();
return v == null ? empty() : ObservableScalarXMap.scalarXMap(v, mapper);
} else {
return RxJavaPlugins.onAssembly(new ObservableFlatMap(this, mapper, delayErrors, maxConcurrency, bufferSize));
}
}
我们看到返回一个ObservableFlatMap实例。当我们调用observable.subscrbe(obverser)的时候,调用到如下方法:
@Override
public void subscribeActual(Observer<? super U> t) {
if (ObservableScalarXMap.tryScalarXMapSubscribe(source, t, mapper)) {
return;
}
source.subscribe(new MergeObserver<T, U>(t, mapper, delayErrors, maxConcurrency, bufferSize));
}
主要看MergeObserver的onNext方法
public void onNext(T t) {
// safeguard against misbehaving sources
if (done) {
return;
}
ObservableSource<? extends U> p;
try {
p = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper returned a null ObservableSource");
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
s.dispose();
onError(e);
return;
}
if (maxConcurrency != Integer.MAX_VALUE) {
synchronized (this) {
if (wip == maxConcurrency) {
sources.offer(p);
return;
}
wip++;
}
}
subscribeInner(p);
}
而mapper.apply(t)即是例子中返回的Observable.from(list),我们继续分析subscribeInner方法:
void subscribeInner(ObservableSource<? extends U> p) {
for (;;) {
if (p instanceof Callable) {
if (tryEmitScalar(((Callable<? extends U>)p)) && maxConcurrency != Integer.MAX_VALUE) {
boolean empty = false;
synchronized (this) {
p = sources.poll();
if (p == null) {
wip--;
empty = true;
}
}
if (empty) {
drain();
break;
}
} else {
break;
}
} else {
InnerObserver<T, U> inner = new InnerObserver<T, U>(this, uniqueId++);
if (addInner(inner)) {
p.subscribe(inner);
}
break;
}
}
}
一般走else语句,进入InnerObserver中,走到InnerObserver的onNext方法
public void onNext(U t) {
if (fusionMode == QueueDisposable.NONE) {
parent.tryEmit(t, this);
} else {
parent.drain();
}
}
一般fusionMode为NONE,调用MergeObserver的tryEmit方法:
void tryEmit(U value, InnerObserver<T, U> inner) {
if (get() == 0 && compareAndSet(0, 1)) {
actual.onNext(value);
if (decrementAndGet() == 0) {
return;
}
} else {
SimpleQueue<U> q = inner.queue;
if (q == null) {
q = new SpscLinkedArrayQueue<U>(bufferSize);
inner.queue = q;
}
q.offer(value);
if (getAndIncrement() != 0) {
return;
}
}
drainLoop();
}
主要看drainLoop方法, drainLoop比较长,大体就是循环接收发射来的数据,并通知子observer接收数据child.onNext();
那么谁发射数据到MergeObserver的,我们上面提到p = Observable.fromInterable(list); 这里就是主要发射数据点, 实际上p为ObservableFromIterable实例,进入具体subscribeActual方法:
public void subscribeActual(Observer<? super T> s) {
Iterator<? extends T> it;
try {
it = source.iterator();
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
EmptyDisposable.error(e, s);
return;
}
boolean hasNext;
try {
hasNext = it.hasNext();
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
EmptyDisposable.error(e, s);
return;
}
if (!hasNext) {
EmptyDisposable.complete(s);
return;
}
FromIterableDisposable<T> d = new FromIterableDisposable<T>(s, it);
s.onSubscribe(d);
if (!d.fusionMode) {
d.run();
}
}
进入FromIterableDisposable的run方法
void run() {
boolean hasNext;
do {
if (isDisposed()) {
return;
}
T v;
try {
v = ObjectHelper.requireNonNull(it.next(), "The iterator returned a null value");
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
actual.onError(e);
return;
}
actual.onNext(v);
if (isDisposed()) {
return;
}
try {
hasNext = it.hasNext();
} catch (Throwable e) {
Exceptions.throwIfFatal(e);
actual.onError(e);
return;
}
} while (hasNext);
if (!isDisposed()) {
actual.onComplete();
}
}
进入for循环,发射数据actual.onNext(v),这个actual是通过组合包装的MergeObserver,于是验证了我们一开始猜测的是正确的。
scan:将发射源的结果作为入参的第一个参数,入参的第二个参数为第i个发射源数据,然后根据自定义的处理结果继续处理。
scan通过看完源码之后会特别容易理解,先举个例子。
Observable.just(1, 2, 3, 4,5)
.scan(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer t1, Integer t2) {
return t1 + t2;//累加操作,
}
})
.subscribe(getObserver())
那么上面的例子,observer将依次接收到1,3,6,10,15
上面的例子中我们主要看scan相关的Observer——ScanObserver。onNext方法如下:
public void onNext(T t) {
if (!this.done) {
Observer<? super T> a = this.actual;
T v = this.value;
if (v == null) {
this.value = t;
a.onNext(t);
} else {
Object u;
try {
u = ObjectHelper.requireNonNull(this.accumulator.apply(v, t), "The value returned by the accumulator is null");
} catch (Throwable var6) {
Exceptions.throwIfFatal(var6);
this.s.dispose();
this.onError(var6);
return;
}
this.value = u;
a.onNext(u);
}
}
}
从上面可以看出,当发射1的时候,this.value为空,因此进入if语句中,输出1,接着发送2的时候,进入else语句,通过this.accumulator.apply(v, t),例子中是进行v+t操作,这里t为上一个发射源结果1,因为1+2,得出3。后面处理结果一样。
reduce:和scan类似,只不过scan会先把结果提交给订阅者输出,而reduce是等所有observable处理完,才把最终结果提交给订阅者处理。
先看个例子:
Observable.just(1, 2, 3, 4)
.reduce(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer t1, Integer t2) {
return t1 + t2;
}
})
.subscribe(getObserver())
主要看reduce方法的对应的Observer——ReduceObserver,onNext方法如下:
public void onNext(T value) {
if (!this.done) {
T v = this.value;
if (v == null) {
this.value = value;
} else {
try {
this.value = ObjectHelper.requireNonNull(this.reducer.apply(v, value), "The reducer returned a null value");
} catch (Throwable var4) {
Exceptions.throwIfFatal(var4);
this.d.dispose();
this.onError(var4);
}
}
}
}
这样,只是先计算出来并保存结果value上。然后在onComplete中输出。
public void onComplete() {
if (!this.done) {
this.done = true;
T v = this.value;
this.value = null;
if (v != null) {
this.actual.onSuccess(v);
} else {
this.actual.onComplete();
}
}
}