前兩篇Android RxJava的使用(一)基本用法艾杏、Android RxJava的使用(二)Action介紹了RxJava的基本用法,對Rxjava還不了解的請先看以上兩篇庸追。這篇為大家講解RxJava中map和flatMap的使用。
參考:給 Android 開發(fā)者的 RxJava 詳解
(本文部分內(nèi)容引用自該博客)
回顧
前兩篇為大家介紹了使用RxJava打印多個字符串的方法
Observable.just("Hellow", "Wrold").subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.i(TAG, s);
}
});
這樣的例子基本沒有實際用處台囱,只是為大家演示如何使用Rxjava淡溯。今天就拋開這個例子。
map
在使用map之前要先說道一個接口:Func1簿训,F(xiàn)unc1和上一篇提到的Action1相似咱娶。Func1 和 Action的區(qū)別在于, Func1 包裝的是有返回值的方法强品。
接下來就是map的用法膘侮,看代碼更直觀點;
例:得到多個Student對象中的name的榛,保存到nameList中
Observable.just(student1, student2, student2)
//使用map進行轉(zhuǎn)換琼了,參數(shù)1:轉(zhuǎn)換前的類型,參數(shù)2:轉(zhuǎn)換后的類型
.map(new Func1<Student, String>() {
@Override
public String call(Student i) {
String name = i.getName();//獲取Student對象中的name
return name;//返回name
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
nameList.add(s);
}
});
可以看到Observable中原來的參數(shù)是Student對象困曙,而最后我們需要的是name表伦,這里使用了map來實現(xiàn)這一轉(zhuǎn)換的過程。當然慷丽,map可以多次使用蹦哼。
//多次使用map,想用幾個用幾個
Observable.just("Hello", "World")
.map(new Func1<String, Integer>() {//將String類型的轉(zhuǎn)化為Integer類型的哈希碼
@Override
public Integer call(String s) {
return s.hashCode();
}
})
.map(new Func1<Integer, String>() {//將轉(zhuǎn)化后得到的Integer類型的哈希碼再轉(zhuǎn)化為String類型
@Override
public String call(Integer integer) {
return integer.intValue() + "";
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.i(TAG, s);
}
});
flatMap
flatMap是一個比教難理解的一個轉(zhuǎn)換要糊,在這里先假設一個需求纲熏,需要打印多個Student所學的課程。這跟之前獲取Student的name又不同了,這里先確定一下關(guān)系局劲,一個Student類中只有一個name勺拣,而一個Student卻有多門課程(Course),Student我們可以理解成這樣:
/**
* 學生類
*/
class Student {
private String name;//姓名
private List<Course> coursesList;//所修的課程
...
}
/**
* 課程類
*/
class Course {
private String name;//課程名
private String id;
...
}
如果使用map來實現(xiàn)打印所有學生所修個課程名鱼填,實現(xiàn)的代碼是這樣的:
List<Student> students = new ArrayList<Student>();
students.add...
...
Action1<List<Course>> action1 = new Action1<List<Course>>() {
@Override
public void call(List<Course> courses) {
//遍歷courses药有,輸出cuouses的name
for (int i = 0; i < courses.size(); i++){
Log.i(TAG, courses.get(i).getName());
}
}
};
Observable.from(students)
.map(new Func1<Student, List<Course>>() {
@Override
public List<Course> call(Student student) {
//返回coursesList
return student.getCoursesList();
}
})
.subscribe(action1);
可以看到,在Action1中出現(xiàn)了for來循環(huán)打印課程名苹丸,使用RxJava就是為了剔除這樣的嵌套結(jié)構(gòu)愤惰,使得整體的邏輯性更強。這時候就可以使用flatMap了赘理,使用flatMap實現(xiàn)的代碼是這樣的:
List<Student> students = new ArrayList<Student>();
students.add...
...
Observable.from(students)
.flatMap(new Func1<Student, Observable<Course>>() {
@Override
public Observable<Course> call(Student student) {
return Observable.from(student.getCoursesList());
}
})
.subscribe(new Action1<Course>() {
@Override
public void call(Course course) {
Log.i(TAG, course.getName());
}
});
這樣就實現(xiàn)了跟上面代碼一樣的效果宦言,看起來有點懵?確實商模,flatMap理解起來有點繞奠旺,剛接觸flatMap的時候我也是懵逼一個。下面我將flatMap的示意圖施流,希望能幫助理解:
由上圖可以看出Student1响疚、Student2經(jīng)過flatMap后,按順序依次經(jīng)歷了Observable1嫂沉、Observable2稽寒,分別轉(zhuǎn)化為Course。最后按順序得到Course1趟章、Course2、Course3慎王、Course4蚓土、Course5、Course6赖淤,其中1-3由Student1得到蜀漆,4-6由Student2得到。
結(jié)合代碼和示意圖咱旱,是不是對flatMap有了一定的理解确丢。
注意:FlatMap對這些Observables發(fā)射的數(shù)據(jù)做的是合并(merge)操作,因此它們可能是交錯的吐限。也就說鲜侥,傳入的順序可能跟出來的順序不一樣。
如果要保證順的的話诸典,可以使用concatMap描函。
其他操作符
除了map和flatMap之外,還有其他操作符以供使用。這里就不一一列舉他們的用法了舀寓,其他常用的操作符如下:
filter:集合進行過濾
each:遍歷集合
take:取出集合中的前幾個
skip:跳過前幾個元素
小結(jié)
看完map胆数、flatMap后,慢慢能看到RxJava的實際用處了互墓。不過只是這點功能的RxJava是遠遠不能滿足我們的需求必尼,更多的用法我只能在后面更新了。今天就到這里吧4勰臁R任椤!
以上有錯誤之處感謝指出
更多:
Android RxJava的使用(四)線程控制 —— Scheduler
參考:給 Android 開發(fā)者的 RxJava 詳解
(本文部分內(nèi)容引用自該博客)