zoukankan      html  css  js  c++  java
  • 【Android】RxJava的使用(三)转换——map、flatMap

    前两篇Android RxJava的使用(一)基本用法Android RxJava的使用(二)Action介绍了RxJava的基本用法,对Rxjava还不了解的请先看以上两篇。这篇为大家讲解RxJava中map和flatMap的使用。

    参考:给 Android 开发者的 RxJava 详解
    (本文部分内容引用自该博客)

    回顾

    前两篇为大家介绍了使用RxJava打印多个字符串的方法

    1 Observable.just("Hellow", "Wrold").subscribe(new Action1<String>() {
    2           @Override
    3           public void call(String s) {
    4               Log.i(TAG, s);
    5           }
    6       });

    这样的例子基本没有实际用处,只是为大家演示如何使用Rxjava。今天就抛开这个例子。

    map

    在使用map之前要先说道一个接口:Func1,Func1和上一篇提到的Action1相似。Func1 和 Action的区别在于, Func1 包装的是有返回值的方法。
    接下来就是map的用法,看代码更直观点;
    例:得到多个Student对象中的name,保存到nameList中

     1 Observable.just(student1, student2, student2)
     2                 //使用map进行转换,参数1:转换前的类型,参数2:转换后的类型
     3                 .map(new Func1<Student, String>() {
     4                     @Override
     5                     public String call(Student i) {
     6                         String name = i.getName();//获取Student对象中的name
     7                         return name;//返回name
     8                     }
     9                 })
    10                 .subscribe(new Action1<String>() {
    11                     @Override
    12                     public void call(String s) {
    13                         nameList.add(s);
    14                     }
    15                 });

    可以看到Observable中原来的参数是Student对象,而最后我们需要的是name,这里使用了map来实现这一转换的过程。当然,map可以多次使用。

     1 //多次使用map,想用几个用几个
     2         Observable.just("Hello", "World")
     3                 .map(new Func1<String, Integer>() {//将String类型的转化为Integer类型的哈希码
     4                     @Override
     5                     public Integer call(String s) {
     6                         return s.hashCode();
     7                     }
     8                 })
     9                 .map(new Func1<Integer, String>() {//将转化后得到的Integer类型的哈希码再转化为String类型
    10                     @Override
    11                     public String call(Integer integer) {
    12                         return integer.intValue() + "";
    13                     }
    14                 })
    15                 .subscribe(new Action1<String>() {
    16                     @Override
    17                     public void call(String s) {
    18                         Log.i(TAG, s);
    19                     }
    20                 });

    flatMap

    flatMap是一个比教难理解的一个转换,在这里先假设一个需求,需要打印多个Student所学的课程。这跟之前获取Student的name又不同了,这里先确定一下关系,一个Student类中只有一个name,而一个Student却有多门课程(Course),Student我们可以理解成这样:

     1 /**
     2      * 学生类
     3      */
     4     class Student {
     5         private String name;//姓名
     6         private List<Course> coursesList;//所修的课程
     7         ...
     8     }
     9     /**
    10      * 课程类
    11      */
    12     class  Course {
    13         private String name;//课程名
    14         private String id;
    15         ...
    16     }

    如果使用map来实现打印所有学生所修个课程名,实现的代码是这样的:

     1 List<Student> students = new ArrayList<Student>();
     2         students.add...
     3         ...
     4 
     5         Action1<List<Course>> action1 = new Action1<List<Course>>() {
     6             @Override
     7             public void call(List<Course> courses) {
     8                 //遍历courses,输出cuouses的name
     9                  for (int i = 0; i < courses.size(); i++){
    10                     Log.i(TAG, courses.get(i).getName());
    11                 }
    12             }
    13         };
    14         Observable.from(students)
    15                 .map(new Func1<Student, List<Course>>() {
    16                     @Override
    17                     public List<Course> call(Student student) {
    18                         //返回coursesList
    19                         return student.getCoursesList();
    20                     }
    21                 })
    22                 .subscribe(action1);

    可以看到,在Action1中出现了for来循环打印课程名,使用RxJava就是为了剔除这样的嵌套结构,使得整体的逻辑性更强。这时候就可以使用flatMap了,使用flatMap实现的代码是这样的:

     1  List<Student> students = new ArrayList<Student>();
     2         students.add...
     3         ...
     4 
     5         Observable.from(students)
     6                 .flatMap(new Func1<Student, Observable<Course>>() {
     7                     @Override
     8                     public Observable<Course> call(Student student) {
     9                         return Observable.from(student.getCoursesList());
    10                     }
    11                 })
    12                 .subscribe(new Action1<Course>() {
    13                     @Override
    14                     public void call(Course course) {
    15                         Log.i(TAG, course.getName());
    16                     }
    17                 });

    这样就实现了跟上面代码一样的效果,看起来有点懵?确实,flatMap理解起来有点绕,刚接触flatMap的时候我也是懵逼一个。下面我将flatMap的示意图,希望能帮助理解:


    flatMap示意图


    由上图可以看出Student1、Student2经过flatMap后,按顺序依次经历了Observable1、Observable2,分别转化为Course。最后按顺序得到Course1、Course2、Course3、Course4、Course5、Course6,其中1-3由Student1得到,4-6由Student2得到。
    结合代码和示意图,是不是对flatMap有了一定的理解。

    其他操作符

    除了map和flatMap之外,还有其他操作符以供使用。这里就不一一列举他们的用法了,其他常用的操作符如下:

    filter:集合进行过滤
    each:遍历集合
    take:取出集合中的前几个
    skip:跳过前几个元素

    更多操作符

    小结

    看完map、flatMap后,慢慢能看到RxJava的实际用处了。不过只是这点功能的RxJava是远远不能满足我们的需求,更多的用法我只能在后面更新了。今天就到这里吧!!!

    以上有错误之处感谢指出

  • 相关阅读:
    客户端负载均衡Feign之一:申明式服务调用Feign入门示例
    客户端负载均衡Ribbon之一:Spring Cloud Netflix负载均衡组件Ribbon介绍
    客户端负载均衡Ribbon之二:Loadbalance的源码
    spring4.0之九:websocket简单应用
    spring4.0之八:Groovy DSL
    spring4.0之七:Ordering Autowired Collections
    spring4.0之六:Generic Qualifier(泛型限定)
    spring4.0之五:@Conditional在满足特定条件下,才会实例化对象
    spring4.0之三:@RestController
    Spring4.0之四:Meta Annotation(元注解)
  • 原文地址:https://www.cnblogs.com/huolongluo/p/6585886.html
Copyright © 2011-2022 走看看