RxJava系列教程之变换篇(三)

来源:互联网 发布:apk软件如何安装 编辑:程序博客网 时间:2024/05/17 16:56

RxJava系列教程:
RxJava系列教程之介绍篇(一)
RxJava系列教程之创建篇(二)
RxJava系列教程之变换篇(三)
RxJava系列教程之过滤篇(四)
RxJava系列教程之线程篇(五)


序言

上次我们介绍了RxJava的各种创建方式,但是那根本不能让我们体会到RxJava的强大之处,所以这节,我们要讲的是RxJava最厉害的地方,变换。
变换要怎样来理解,那就是,假设observable发送的数据是String类型的,一个变换的操作符,就可以变成Integer类型,之后的链式操作就是integer类型的数据了。
这样说可能太简单了,我们换个说法,假设你写了一个Student类,里面有个subject集合,你给observable传递一个Student类,然后转化成ArrayList,然后你又转化成observable.from(集合),然后又转化成String,然后各种使用这个String,嗯嗯,这样应该比较符合平时开发的场景。

变换

最基础的变化操作符——map
map操作符的主要作用就是使T类型的数据转化为R类型的数据。
我们先来看看map的使用形状:

        Observable            .just(1, 2, 3)            .map(new Func1<Integer, String>()            {                @Override                public String call(Integer i)                {                    return "数字:" + i;                }            }).subscribe(new Action1<String>()            {                @Override                public void call(String str)                {                    System.out.println(str);                }            });

运行结果:

数字:1数字:2数字:3

我们发现在使用map的时候,引入了一个新的类,Func1,我们来看看这个类的真面目:

        new Func1<T, R>()        {            @Override            public R call(T arg0)            {                return null;            }        };

这里面有2个泛型,T和R,T就是转换前的类型,上面的例子就是String,R就是转换后的类型,然后这个回调方法就是转换的过程,这是由我们来控制的。T和R都是泛型,所以,我们不仅可以写基础的类,当然也可以写我们自己创建的类,这样,灵活性是不是非常大。

接下来我们介绍下第二个变换类型:flatMap
在介绍这个操作符之前,我先来说明一下,当你们看到map操作符,会发现已经很强大了,那为什么还要引入这个操作符呢,既然都是变换,那么map不就可以hold住所有的变换了吗,没错。其实我是这样理解这个操作符的,rxjava的作者觉得我们无法完美体会到map操作符的各种巧妙的运用,所以给我们了一个新的操作符。好了,话不多说,我先来告诉你们这个操作符是什么转化成什么的。

flatMap:将T类型,转化为observable<R>

看不懂?来张官方图?
这里写图片描述
我先解释下这张图片的含义,如果看不懂,可以继续往下看,看了下面的例子后,再回过头来看这个解析吧

图片解析:最上面这个箭头上的圆代表observable发送的数据,数据类型都是圆。经过flatMap后,将圆转化成了observable<菱形>,然后每个圆可以转化成2个菱形。现在的情况就是,有3个圆数据,经过flatMap之后转化成了3个observable<菱形>,每个observable<菱形>都有2条数据。因为是observable,所以又可以发送数据了,数据类型就是<菱形>了。大概是这个意思。
也就是说,flatMap可以将发射的数据转化为observable,然后再进行发射。

来,我们来写个例子。
student类:

public class Student{    private String id;    private String name;    private String gender;    private int age;    private String tel;    private ArrayList<Subject> arrayList;    public ArrayList<Subject> getArrayList()    {        return arrayList;    }    public Student setArrayList(ArrayList<Subject> arrayList)    {        this.arrayList = arrayList;        return this;    }    public String getId()    {        return id;    }    public Student setId(String id)    {        this.id = id;        return this;    }    public String getName()    {        return name;    }    public Student setName(String name)    {        this.name = name;        return this;    }    public String getGender()    {        return gender;    }    public Student setGender(String gender)    {        this.gender = gender;        return this;    }    public int getAge()    {        return age;    }    public Student setAge(int age)    {        this.age = age;        return this;    }    public String getTel()    {        return tel;    }    public Student setTel(String tel)    {        this.tel = tel;        return this;    }}

Subject类

public class Subject{    private String subName;    private String subTeacher;    public String getSubName()    {        return subName;    }    public Subject setSubName(String subName)    {        this.subName = subName;        return this;    }    public String getSubTeacher()    {        return subTeacher;    }    public Subject setSubTeacher(String subTeacher)    {        this.subTeacher = subTeacher;        return this;    }}

可以看出,student类里面有个集合,这个前提能够让我们发送集合里面的数据,就可以作为一个observable。
假设我们要获取每个学生所学的科目,我们就可以:

        Observable            .just(student1, student2, student3)            .flatMap(new Func1<Student, Observable<Subject>>()            {                @Override                public Observable<Subject> call(Student student)                {                    System.out.println("学生名字:" + student.getName());                    return Observable.from(student.getArrayList());                }            }).subscribe(new Action1<Subject>()            {                @Override                public void call(Subject subject)                {                    System.out.println(subject.getSubName() + " ");                }            });

运行结果:

学生名字:张三语文 数学 学生名字:李四英语 物理 学生名字:王五化学 生物 

我们可以看到,通过flatMap之后,原来的student转化成了observable<Subject>,然后又可以快乐的发射数据了。
我们来尝试用map来实现相同的效果

        Observable            .just(student1, student2, student3)            .map(new Func1<Student, Observable<Subject>>()            {                @Override                public Observable<Subject> call(Student student)                {                    System.out.println("学生名字:" + student.getName());                    return Observable.from(student.getArrayList());                }            }).subscribe(new Action1<Observable<Subject>>()            {                @Override                public void call(Observable<Subject> observable)                {                    observable.subscribe(new Action1<Subject>()                    {                        @Override                        public void call(Subject subject)                        {                            System.out.println(subject.getSubName());                        }                    });                }            });

运行结果:

学生名字:张三语文数学学生名字:李四英语物理学生名字:王五化学生物

我们发现,使用map也能实现相同的效果,但是这样实现的效果未免太不完美了,也不优雅,最重要的就是他让我们失去了rxjava最引以为豪的链式操作。
由此,我们可以感觉到flatmap的强大之处。

总结

map:将T类型的数据转化为R类型的数据flatMap:将T类型的数据转化为observable<R>类型,或者说,将T类型转化为observable让你继续快乐的使用各种操作符

下集预告:本章我讲解了rxjava中常用的变换操作符,在下一章,我们讲会了解rxjava的过滤系统,在下篇文章我们能够知道,当有很多数据的时候,我们如何在这些数据中筛选出我们需要的数据。

原创粉丝点击