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

简介

之前一篇文章讲解了 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)
//count:缓存区的最大数量;skip:向前跳过的项数;如果count=skip,相当于buffer(int count);
.buffer(2, 1)
.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)
//count:缓存区的最大数量;skip:向前跳过的项数;如果count=skip,相当于buffer(int count);
.window(2)
.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 + "the 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 {
    //调用Function的apply(),并返回结果,v就是返回的结果;
    v = ObjectHelper.requireNonNull(mapper.apply(t), "The mapper function returned a null value.");
  } catch (Throwable ex) {
    fail(ex);
    return;
  }
  actual.onNext(v);//发送事件给订阅者;
}

以map()方法简单的转换的过程;内部原理就是:将发射的事件,在Transforming操作符相关类中订阅,在onNext()方法中按一定的方式转换,成功后;再将转换后的值作为新事件的的参数,再次发送出去;

上面就是Transforming操作符的常见用法和内部转换逻辑及原理;如有问题,请多指教!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值