distinct的作用是阻止已经发射过的数据,简单来说就是用来去重
Observable.fromArray("1","2","3","4","1","2")
.distinct()
.subscribe(new Consumer<String>() {
@Override
public void accept(String str) throws Exception {
System.out.println(str);
}
});
输出 1 2 3 4 ,后面的1 2 就不再发射了。
看看源码
createHashSet就是创建HashSet,发射过的数据会被添加到HashSet中,如果添加成功,就会把数据发射出来,如果失败,就丢弃该数据。
public final Observable<T> distinct() {
return distinct(Functions.identity(), Functions.createHashSet());
}
public final <K> Observable<T> distinct(Function<? super T, K> keySelector, Callable<? extends Collection<? super K>> collectionSupplier) {
...
return RxJavaPlugins.onAssembly(new ObservableDistinct<T, K>(this, keySelector, collectionSupplier));
}
public final class ObservableDistinct<T, K> extends AbstractObservableWithUpstream<T, T> {
final Function<? super T, K> keySelector;
final Callable<? extends Collection<? super K>> collectionSupplier;
public ObservableDistinct(ObservableSource<T> source, Function<? super T, K> keySelector, Callable<? extends Collection<? super K>> collectionSupplier) {
super(source);
this.keySelector = keySelector;
this.collectionSupplier = collectionSupplier;
}
@Override
protected void subscribeActual(Observer<? super T> observer) {
Collection<? super K> collection;
try {
// 这里就是 HashSet
collection = ObjectHelper.requireNonNull(collectionSupplier.call(), "The collectionSupplier returned a null collection. Null values are generally not allowed in 2.x operators and sources.");
} catch (Throwable ex) {
Exceptions.throwIfFatal(ex);
EmptyDisposable.error(ex, observer);
return;
}
source.subscribe(new DistinctObserver<T, K>(observer, keySelector, collection));
}
...
}
到DistinctObserver的onNext方法。因为用Functions.identity()创建的keySelector,所以返回的还是原来的对象,没有转换,主要就是利用HashSet的add方法,添加失败,说明已经发射过该数据了,就会丢弃该数据,如果成功,就会把数据发射到下游。
public void onNext(T value) {
if (done) {
return;
}
if (sourceMode == NONE) {
K key;
boolean b;
try {
//
key = ObjectHelper.requireNonNull(keySelector.apply(value), "The keySelector returned a null key");
//添加成功,就可以把数据发射出去。
b = collection.add(key);
} catch (Throwable ex) {
fail(ex);
return;
}
if (b) {
downstream.onNext(value);
}
} else {
downstream.onNext(null);
}
}