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

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的过滤系统,在下篇文章我们能够知道,当有很多数据的时候,我们如何在这些数据中筛选出我们需要的数据。

猜你喜欢

转载自blog.csdn.net/it_xf/article/details/74316327