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