当前位置:   article > 正文

RxJava的学习之变换操作符—flatMap_rxjava flatmap

rxjava flatmap

1、FlatMap

(1)FlatMap

官方流程图:
这里写图片描述

定义:FlatMap操作符使用一个指定的函数对原始Observable发射的每一项数据执行变换操作,这个函数返回一个本身也发射数据的Observable,然后FlatMap合并这些Observables发射的数据,最后将合并后的结果当做它自己的数据序列发射。

格式:
Javadoc: flatMap(Func1))
Javadoc: flatMap(Func1,int))
  • 1
  • 2
  • 3

      这个操作符有一个接受额外的int参数的一个变体。这个参数设置flatMap从原来的Observable映射Observables的最大同时订阅数。当达到这个限制时,它会等待其中一个终止然后再订阅另一个。

注意:FlatMap对这些Observables发射的数据做的是合并(merge)操作,因此它们可能是交错的,即不能保证数据的发射顺序。

代码示例:
      继续上一篇的内容,让我们来看一Rxjava 的简洁性
改变一下Map篇的代码内容,如下
例1

 Observable.just(p1,p2,p3).flatMap(new Func1<Person, Observable<Cat>>() {
      @Override public Observable<Cat> call(Person person) {
        return Observable.from(person.getCats());
      }
    }).subscribe(new Action1<Cat>() {
      @Override public void call(Cat cat) {
        System.out.println("输出结果:" + cat.getName());
      }
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

从上面的代码可以看出相比Map的代码没有了for循环的困扰,让程序看起来更加的简洁。

例2

  List<String> list=new ArrayList<>();
    list.add("image1");
    list.add("image2");
    list.add("image3");
    Observable.just(list).flatMap(new Func1<List<String>, Observable<List<String>>>() {
      @Override public Observable<List<String>> call(List<String> strings) {
       List<String> str=new ArrayList<String>();
        for(String s:strings){
          str.add(s+".jpeg");
        }
        return Observable.just(str);
      }
    }).subscribe(new Action1<List<String>>() {

      @Override public void call(List<String> strings) {
        for(String s:strings){
          System.out.println("输出结果->"+s);
        }

      }
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

这里写图片描述

(2)flatMapIterable这个变体成对的打包数据,然后生成Iterable而不是原始数据和生成的Observables,但是处理方式是相同的。

  Observable.just(1,2,3).flatMapIterable(new Func1<Integer, List<Integer>>() {
      @Override public List<Integer> call(Integer integer) {
        List<Integer> list = new ArrayList<Integer>();
        list.add(integer);
        return list;
      }
    }).subscribe(new Action1<Integer>() {
      @Override public void call(Integer integer) {
        System.out.println("输出结果->"+integer);
      }
    });
  }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

这里写图片描述

上面例子看不出他的数据交错,再看一下下面的例子

 Observable.just(1,2,3,4,5,6).flatMap(new Func1<Integer, Observable<Integer>>() {
      @Override
      public Observable<Integer> call(Integer integer) {
        int time=1;
        if(integer%2==0)
            time=2;
        return Observable.just(integer).delay(time,TimeUnit.SECONDS);
      }
    }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
      @Override
      public void call(Integer integer) {
       Log.d("flatMap", String.valueOf(integer));
      }
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

运行结果:数据输出顺序不一致
这里写图片描述

2、concatMap

      concatMap操作符,它类似于最简单版本的flatMap,但是它按次序连接而不是合并那些生成的Observables,然后产生自己的数据序列。
它的操作跟flatMap一样的。
官方流程图:
官方流程图

代码示例:

 Observable.just(1,2,3,4,5,6).concatMap(new Func1<Integer, Observable<Integer>>() {
      @Override
      public Observable<Integer> call(Integer integer) {
        int time=1;
        if(integer%2==0)
            time=2;
        return Observable.just(integer).delay(time,TimeUnit.SECONDS);
      }
    }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
      @Override
      public void call(Integer integer) {
       Log.d("concatMap", String.valueOf(integer));
      }
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

运行结果:数据输出顺序是一致的

这里写图片描述

3、switchMap

      RxJava还实现了switchMap操作符。它和flatMap很像,除了一点:当原始Observable发射一个新的数据(Observable)时,它将取消订阅并停止监视产生之前那个数据的Observable,只监视当前这一个。

这里写图片描述

代码示例:

 Observable.just(1,2,3,4,5,6).switchMap(new Func1<Integer, Observable<Integer>>() {
      @Override
      public Observable<Integer> call(Integer integer) {
        int time=1;
        if(integer%2==0)
            time=2;
        return Observable.just(integer).delay(time,TimeUnit.SECONDS);
      }
    }).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
      @Override
      public void call(Integer integer) {
       Log.d("switchMap", String.valueOf(integer));
      }
    });
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

运行结果:数据输出只剩下最后一个值
这里写图片描述

4、总结

      从上面的代码和运行结果可以看出各个操作符的用法和区别。flatMap合并的数据可能出现交错的情况,导致数据输出顺序不一致。concatMap正好跟flatMap相反。switchMap在发射数据的时候,只会发射最新的数据,放弃旧的数据。如果还看不懂多演练几遍,体会一下,一般都能达到事半功倍的效果。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/177405
推荐阅读
相关标签
  

闽ICP备14008679号