Rxjava2 distinct

239 阅读1分钟

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));
    }
    ...
    
    }

DistinctObserveronNext方法。因为用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);
            }
        }