RxJava2.0-操作符-Transforming和内部转换逻辑及原理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fengluoye2012/article/details/79182199
简介
之前一篇文章讲解了 RxJava2.0-操作符-Creating用法,现在来看下Transforming(转换操作符 ),主要是将一种类型或者值转换为另一种类型或者值;主要有一下几种方法分别是:
map:将传入值 根据一定规则去转换,然后返回结果,简单的转换;
flatMap:将集合转换成单个的元素;
scan:相当于叠加算法,将当前的值和前n个值的和相加
buffer:将单个元素,分组,组合成集合;
groupBy:将单个元素,分组,发送顺序不变;
window:window和buffer很相似;
用法
1)map:可以不改变参数类型;也可以改变参数的类型
final String[] arr = {"1", "45", "789"};
//Function接口获取一个值,返回一个值,返回值可能是不同类型的;
Observable.fromArray(arr)
.map(new Function<String, Integer>() {
  @Override
  public Integer apply(@NonNull String s) throws Exception {
    return s.length();
  }
}) 
.subscribe(new Consumer<Integer>() {
  @Override
  public void accept(Integer s) throws Exception {
    Log.e(tag, String.valueOf(s));
  }
});
运行结果
2)flatMap:将集合转换成单个的元素;
final List<String> list = new ArrayList<>();
list.add("第一个");
list.add("第二个");
list.add("第三个");
//flatMap:将集合转换成单个的元素;
Observable.just(list).flatMap(new Function<List<String>, Observable<String>>() {
  @Override
  public Observable<String> apply(@NonNull List<String> strings) throws Exception {
    return Observable.fromIterable(strings);
  }
}).subscribe(new Consumer<String>() {
  @Override
  public void accept(String s) throws Exception {
    Log.e(tag, "flatMap" + s);
  }
});
运行结果
3)scan:相当于叠加算法,将当前的值和前n个值的和相加
//BiFunction接口,根据多个输入值按照一定规则组合,返回组合的结果
Observable.just(3, 4, 5, 6).scan(new BiFunction<Integer, Integer, Integer>() {
  @Override
  public Integer apply(@NonNull Integer integers, @NonNull Integer integers2) throws Exception {
    Log.e(tag, "integers:" + integers + ",integers2:" + integers2);
    return integers + integers2;
  }
}).subscribe(new Consumer<Integer>() {
  @Override
  public void accept(Integer integer) throws Exception {
    Log.e(tag, "scan+flatMap::" + String.valueOf(integer));
  }
});
运行结果
从结果可以看出:integers是前面(n-1)的累加值;integers2为第n个值;
4)buffer:将单个元素,分组,组合成集合;
Observable.just(1, 2, 3, 4, 5, 6)
.buffer(2, 1)//count:缓存区的最大数量;skip:向前跳过的项数;如果count=skip,相当于buffer(int count);
.subscribe(new Consumer<List<Integer>>() {
  @Override
  public void accept(List<Integer> integers) throws Exception {
    Log.e(tag, "buffer分组");
    for (Integer integer : integers) {
      Log.e(tag, String.valueOf(integer));
    }
  }
});
运行结果:
5)groupBy:将单个元素,分组,发送顺序不变;
Observable.just(1, 2, 3, 4, 5, 6)
.groupBy(new Function<Integer, Integer>() {
  @Override
  public Integer apply(@NonNull Integer integer) throws Exception {
    return integer % 3;
  }
})
.subscribe(new Consumer<GroupedObservable<Integer, Integer>>() {
  @Override
  public void accept(final GroupedObservable<Integer, Integer> integerIntegerGroupedObservable) throws Exception {
    integerIntegerGroupedObservable.subscribe(new Consumer<Integer>() {
      @Override
      public void accept(Integer integer) throws Exception {
        Log.e(tag, "Grouped key::" + integerIntegerGroupedObservable.getKey() + ":" + integer);
      }
    });
  }
});
运行结果:
6)window:window和buffer很相似;将单个元素,分组,组合成集合;
Observable.just(10, 11, 12, 13, 14)
.window(2)//count:缓存区的最大数量;skip:向前跳过的项数;如果count=skip,相当于buffer(int count);
.subscribe(new Consumer<Observable<Integer>>() {
  @Override
  public void accept(Observable<Integer> integerObservable) throws Exception {
    Log.e(tag, "window");
    integerObservable.subscribe(new Consumer<Integer>() {
      @Override
      public void accept(Integer integer) throws Exception {
        Log.e(tag, String.valueOf(integer));
      }
    });
  }
});
运行结果:
以map来分析Transforming的内部原理;
以下面的例子为例
final String[] arr = {"1", "45", "789"};
//Function接口获取一个值,返回一个值,返回值可能是不同类型的;
Observable.fromArray(arr)
.map(new Function<String, Integer>() {
  @Override
  public Integer apply(@NonNull String s) throws Exception {
    return s.length();
  }
}) 
.subscribe(new Consumer<Integer>() {
  @Override
  public void accept(Integer s) throws Exception {
    Log.e(tag, String.valueOf(s));
  }
});
先调用fromArray;初始化ObservableFromArray类,
public static <T> Observable<T> fromArray(T... items) {
  ObjectHelper.requireNonNull(items, "items is null");
  if (items.length == 0) {
    return empty();
  } else
    if (items.length == 1) {
      return just(items[0]);
  }
  return RxJavaPlugins.onAssembly(new ObservableFromArray<T>(items));//onAssembly关联hook方法;
}
调用ObservableFromArray类的构造函数之后,初始化ObservableMap类,
ObservableMap类
final Function<? super T, ? extends U> function;
//source为ObservableFromArray;function为map中的参数(new 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));
}
subscribeActual方法中,ObservableSource订阅MapObserver,也就是说ObservableMap中有一个匿名的Observer;
订阅之后,在ObservableFromArray类中执行
@Override
public void subscribeActual(Observer<? super T> s) {// s 为ObservableMap中的MapObserver
  FromArrayDisposable<T> d = new FromArrayDisposable<T>(s, array);
  s.onSubscribe(d);
  if (d.fusionMode) {
    return;
  }
  d.run();
}
在run()方法中
void run() {
  T[] a = array;
  int n = a.length;
  for (int i = 0; i < n && !isDisposed(); i++) {
    T value = a[i];
    if (value == null) {
      actual.onError(new NullPointerException("The " + i + "th element is null"));
      return;
    }
    actual.onNext(value);//ObservableMap中的MapObserver调用onNext()
  }
  if (!isDisposed()) {
    actual.onComplete();//
  }
}
执行ObservableMap类中的MapObserver的onNext()方法
@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.");//调用Function的apply(),并返回结果,v就是返回的结果;
  } catch (Throwable ex) {
    fail(ex);
    return;
  }
  actual.onNext(v);//发送事件给订阅者;
}
以map()方法简单的转换的过程;内部原理就是:将发射的事件,在Transforming操作符相关类中订阅,在onNext()方法中按一定的方式转换,成功后;再将转换后的值作为新事件的的参数,再次发送出去;
上面就是Transforming操作符的常见用法和内部转换逻辑及原理;如有问题,请多指教!

猜你喜欢

转载自blog.csdn.net/fengluoye2012/article/details/79182199