Rxjava2 distinctUntilChanged

635 阅读1分钟

distinctUntilChanged 操作符将阻止 Observable 发出相同的元素。如果后一个元素和前一个元素是相同的,那么这个元素将不会被发出来。如果后一个元素和前一个元素不相同,那么这个元素才会被发出来,简单里说用来过滤掉连续的重复数据。

 Observable.fromArray("1","2","3","3","4","1","2")
                .distinctUntilChanged()
                .subscribe(new Consumer<String>() {
                    @Override
                    public void accept(String str) throws Exception {
                        System.out.println(str);
                    }
                });

输出1 2 3 4 1 2,中间的3没有被发出来。

看看源码

  public final Observable<T> distinctUntilChanged() {
        return distinctUntilChanged(Functions.identity());
    }
    
   public final <K> Observable<T> distinctUntilChanged(Function<? super T, K> keySelector) {
        ...
        return RxJavaPlugins.onAssembly(new ObservableDistinctUntilChanged<T, K>(this, keySelector, ObjectHelper.equalsPredicate()));
    }
    
public final class ObservableDistinctUntilChanged<T, K> extends AbstractObservableWithUpstream<T, T> {

  final Function<? super T, K> keySelector;

  final BiPredicate<? super K, ? super K> comparer;

  public ObservableDistinctUntilChanged(ObservableSource<T> source, Function<? super T, K> keySelector, BiPredicate<? super K, ? super K> comparer) {
      super(source);
      this.keySelector = keySelector;
      this.comparer = comparer;
  }

  @Override
  protected void subscribeActual(Observer<? super T> observer) {
      source.subscribe(new DistinctUntilChangedObserver<T, K>(observer, keySelector, comparer));
  }
  
  ...
  }

DistinctUntilChangedObserveronNext方法,就是在与上一次发射来的数据比较,相等的数据不会发射出来,不相等的数据可以发射出来,并且更新到最新的值。

public void onNext(T t) {
            if (done) {
                return;
            }
            if (sourceMode != NONE) {
                downstream.onNext(t);
                return;
            }

            K key;

            try {
                key = keySelector.apply(t);
                if (hasValue) {
                    //与上次发射来的值比较
                    boolean equal = comparer.test(last, key);
                    last = key;
                    if (equal) {
                        // 一样的数据就可以直接返回
                        return;
                    }
                } else {
                    hasValue = true;
                    last = key;
                }
            } catch (Throwable ex) {
               fail(ex);
               return;
            }
             //不相等的数据可以直接发送
            downstream.onNext(t);
        }