注:本文摘自《RxJava Essentials》翻译中文版电子书
*map家族
Map
map函数接收一个指定的Func对象然后将它应用到每一个由Observable发射的值上。例子:
private void loadList(List<AppInfo> apps) {
Observable.from(apps)
.map(new Func1<AppInfo,AppInfo>(){
@Override
public Appinfo call(AppInfo appInfo){
String currentName = appInfo.getName();
String lowerCaseName = currentName.toLowerCase();
appInfo.setName(lowerCaseName);
return appInfo;
}
})
.subscribe(...);
}
上面例子实现了能够显示同样的列表,但是又要所有的名字都小写。
FlatMap
如果有这样一个需求:我们有一个这样的Observable,它发射一个数据序列,这些数据本身也可以发射Observable,这时候可以使用FlatMap。
当我们在处理可能有大量的Observables时,重要是记住任何一个Observables发生错误的情况,flatMap()将会触发它自己的onError()函数并放弃整个链。
重要的一点提示是关于合并部分:它允许交叉。如下图
这意味着flatMap()不能够保证在最终生成的Observable中源Observables确切的发射顺序。
ConcatMap
concatMap()函数解决了flatMap()的交叉问题,提供了一种能够把发射的值连续在一起的铺平函数,而不是合并它们。
FlatMapIterable
flatMapInterable()和flatMap()很像。仅有的本质不同是它将源数据两两结成对并生成Iterable,而不是原始数据项和生成的Observables。
SwitchMap
switchMap()和flatMap()很像,除了一点:每当源Observable发射一个新的数据项(Observable)时,它将取消订阅并停止监视之前那个数据项产生的Observable,并开始监视当前发射的这一个。
Scan
scan()函数可以看做是一个累积函数。scan()函数对原始Observable发射的每一项数据都应用一个函数,计算出函数的结果值,并将该值填充回可观测序列,等待和下一次发射的数据一起使用。
一个累加器例子:
Observable.just(1,2,3,4,5)
.scan((sum,item) -> sum + item)
.subscribe(...);
输出结果是:1,3,6,10,15
比较每个安装应用的名字从而创建一个名字长度递增的列表:
private void loadList(List<AppInfo> apps) {
Observable.from(apps)
.scan((appInfo,appInfo2) -> {
if(appInfo.getName().length > appInfo2.getName().length()){
return appInfo;
} else {
return appInfo2;
}
})
.distinct()
.subscribe(...);
}
GroupBy
groupBy() 是分组元素,依然是那个例子,我们想按照最近更新日期来排序我们的App时该怎么办?
Observable<GroupedObservable<String,AppInfo>> groupedItems = Observable.from(apps)
.groupBy(new Func1<AppInfo,String>(){
@Override
public String call(AppInfo appInfo){
SimpleDateFormat formatter = new SimpleDateFormat("MM/yyyy");
return formatter.format(new Date(appInfo.getLastUpdateTime()));
}
});
Observable.concat(groupedItems)
.subscribe(...);
GroupedObservable是一个特殊的Observable,它源自一个分组的key。在这个例子中,key就是String,代表的意思是Month/Year格式化的最近更新日期。最后,我们将创建一个新的Observable将所有的联系起来。
Buffer
buffer()函数将源Observable变换一个新的Observable,这个新的Observable每次发射一组列表值而不是一个一个发射。
上图中展示了buffer()如何将count作为一个参数来指定有多少数据项被包在发射的列表中。实际上,buffer()函数有几种变体。其中有一个是允许你指定一个skip值:此后每skip项数据,然后又用count项数据填充缓冲区。如下图所示:
buffer()带一个timespan的参数,会创建一个每隔timespan时间段就会发射一个列表的Observable。
Window
window()函数和buffer()很像,但是它发射的是Observable而不是列表。
Cast
它是map()操作符的特殊版本。它将源Observable中的每一项数据都转换为新的类型,把它变成了不同的Class。