在上一篇文章中,我们介绍了RxJava2的基本简单实用,在本篇文章中,我们将继续学习RxJava2中的常用操作符
操作符之变换
Map:
首先是变换操作符- > Map,(此处引入以前看过的一篇文章的一句话:不知道Map已经统治世界了么?)那么在RxJava2中,Map究竟是个什么鬼.
map是RxJava中最简单的一个变换操作符,它的作用是将上游发送过来的事件都去应用一个函数,让每一个事件都按照该函数去变化,下游接收到事件时,就变成了变化过后的事件,多说无益,上代码.
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}).map(new Function() {
@Override
public String apply(Integer integer) throws Exception {
return "我是变换过后的" + integer;
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.e("XYK",s);
}
});
}
运行结果:
通过运行结果可以看到,我们在上游发送的数据类型为Integer,到了下游接收到的数据为String类型,中间通过map对其进行了转换,是不是感觉很强大?通过map我们可以将上游数据转化为任意类型发送到下游,就是这么6~
图解:
圆形事件1,2,3,经过Map转化之后,变成了三角形事件1,2,3,但是有童鞋要问了,这有什么用呢,我们来举一个实际需求的例子,用Map来做一下:
读取一篇英文文章,将文章中的字符全部转换为大写.
我们先来用非RxJava2来做一下:
//模拟一篇文章
String article = "fkjdsalijfofldaJFOIEjfldanlJR2OnfldajilwafkndaIUPO32,LFKjlijuJFLMA";
char[] chars = article.toCharArray();
StringBuffer sb = new StringBuffer();
for (int i = 0; i < chars.length; i++) {
Log.e(TAG,chars[i] + "");
if(chars[i] >= 'a' && chars[i] <= 'z'){
sb.append((chars[i] + "").toUpperCase());
}else{
sb.append(chars[i]);
}
}
Log.e(TAG,sb.toString());
好像看上去没什么问题,但是这逼格显然不够高,程序员的精髓不就是要敲出一段逼格超高的代码么,我们试试用RxJava2:
//模拟一篇文章
String article = "fkjdsalijfofldaJFOIEjfldanlJR2OnfldajilwafkndaIUPO32,LFKjlijuJFLMA";
final char[] chars = article.toCharArray();
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
for (int i = 0; i < chars.length; i++) {
e.onNext(chars[i]);
}
}
//delay 延时5秒发送
}).delay(5, TimeUnit.SECONDS)
//事件类型转换
.map(new Function() {
@Override
public String apply(Character s) throws Exception {
if (s >= 'a' && s <= 'z') {
return s.toString().toUpperCase();
} else {
return s.toString();
}
}
})
//线程调度
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.e(TAG, s);
}
});
瞬间逼格就上去了,而且还做了线程调度等操作,是不是心头顿时感觉一串666飘过,这仅仅是最基础的转化操作符,接下来我们在看一个FlatMap:
FlatMap
FlatMap,上来就看到map,这个操作符和刚才的map有什么区别呢,flatmap可以将上游发送过来的数据,变换为多个数据,然后合并为一个事件发送到下游,这么说是不是有点难懂?恩,还是直接上代码:
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}).flatMap(new Function>() {
@Override
public ObservableSource apply(Integer integer) throws Exception {
List list = new ArrayList();
for (int i = 0; i < 5; i++) {
list.add("我是变换过的" + integer);
}
return Observable.fromIterable(list);
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.e("XYK", s);
}
});
}
运行结果:
图解:
通过运行结果可以看到,上游发送的数据在到达flatmap的时候,经过处理,将每个事件变成了5个,而后将5个合并为1个事件发送到下游,并且我们可以注意到,发送到下游的数据是无序的,那么这时候就要说了,我要接收的事件是有序的怎么办,这就是接下来要说的concatMap.
ConcatMap:
ConcatMap和FlatMap一样,只不过一个是有序,一个是无序而已,我们直接把上边的代码做一个更改:
Observable.create(new ObservableOnSubscribe() {
@Override
public void subscribe(ObservableEmitter e) throws Exception {
e.onNext(1);
e.onNext(2);
e.onNext(3);
}
}).concatMap(new Function>() {
@Override
public ObservableSource apply(Integer integer) throws Exception {
List list = new ArrayList();
for (int i = 0; i < 5; i++) {
list.add("我是变换过的" + integer);
}
return Observable.fromIterable(list);
}
}).subscribe(new Consumer() {
@Override
public void accept(String s) throws Exception {
Log.e("XYK", s);
}
});
}
运行结果:
可以看到这时候接收到的就是有序的.
图解:
结尾
好啦,变换操作符就讲到这里,下期预告,RxJava2之过滤操作符篇,感谢观看.