赞
踩
(1)FlatMap
官方流程图:
定义:FlatMap操作符使用一个指定的函数对原始Observable发射的每一项数据执行变换操作,这个函数返回一个本身也发射数据的Observable,然后FlatMap合并这些Observables发射的数据,最后将合并后的结果当做它自己的数据序列发射。
格式:
Javadoc: flatMap(Func1))
Javadoc: flatMap(Func1,int))
这个操作符有一个接受额外的int参数的一个变体。这个参数设置flatMap从原来的Observable映射Observables的最大同时订阅数。当达到这个限制时,它会等待其中一个终止然后再订阅另一个。
注意:FlatMap对这些Observables发射的数据做的是合并(merge)操作,因此它们可能是交错的,即不能保证数据的发射顺序。
代码示例:
继续上一篇的内容,让我们来看一Rxjava 的简洁性
改变一下Map篇的代码内容,如下
例1
Observable.just(p1,p2,p3).flatMap(new Func1<Person, Observable<Cat>>() {
@Override public Observable<Cat> call(Person person) {
return Observable.from(person.getCats());
}
}).subscribe(new Action1<Cat>() {
@Override public void call(Cat cat) {
System.out.println("输出结果:" + cat.getName());
}
});
从上面的代码可以看出相比Map的代码没有了for循环的困扰,让程序看起来更加的简洁。
例2
List<String> list=new ArrayList<>();
list.add("image1");
list.add("image2");
list.add("image3");
Observable.just(list).flatMap(new Func1<List<String>, Observable<List<String>>>() {
@Override public Observable<List<String>> call(List<String> strings) {
List<String> str=new ArrayList<String>();
for(String s:strings){
str.add(s+".jpeg");
}
return Observable.just(str);
}
}).subscribe(new Action1<List<String>>() {
@Override public void call(List<String> strings) {
for(String s:strings){
System.out.println("输出结果->"+s);
}
}
});
(2)flatMapIterable这个变体成对的打包数据,然后生成Iterable而不是原始数据和生成的Observables,但是处理方式是相同的。
Observable.just(1,2,3).flatMapIterable(new Func1<Integer, List<Integer>>() {
@Override public List<Integer> call(Integer integer) {
List<Integer> list = new ArrayList<Integer>();
list.add(integer);
return list;
}
}).subscribe(new Action1<Integer>() {
@Override public void call(Integer integer) {
System.out.println("输出结果->"+integer);
}
});
}
上面例子看不出他的数据交错,再看一下下面的例子
Observable.just(1,2,3,4,5,6).flatMap(new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(Integer integer) {
int time=1;
if(integer%2==0)
time=2;
return Observable.just(integer).delay(time,TimeUnit.SECONDS);
}
}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.d("flatMap", String.valueOf(integer));
}
});
运行结果:数据输出顺序不一致
concatMap操作符,它类似于最简单版本的flatMap,但是它按次序连接而不是合并那些生成的Observables,然后产生自己的数据序列。
它的操作跟flatMap一样的。
官方流程图:
代码示例:
Observable.just(1,2,3,4,5,6).concatMap(new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(Integer integer) {
int time=1;
if(integer%2==0)
time=2;
return Observable.just(integer).delay(time,TimeUnit.SECONDS);
}
}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.d("concatMap", String.valueOf(integer));
}
});
运行结果:数据输出顺序是一致的
RxJava还实现了switchMap操作符。它和flatMap很像,除了一点:当原始Observable发射一个新的数据(Observable)时,它将取消订阅并停止监视产生之前那个数据的Observable,只监视当前这一个。
代码示例:
Observable.just(1,2,3,4,5,6).switchMap(new Func1<Integer, Observable<Integer>>() {
@Override
public Observable<Integer> call(Integer integer) {
int time=1;
if(integer%2==0)
time=2;
return Observable.just(integer).delay(time,TimeUnit.SECONDS);
}
}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.d("switchMap", String.valueOf(integer));
}
});
运行结果:数据输出只剩下最后一个值
从上面的代码和运行结果可以看出各个操作符的用法和区别。flatMap合并的数据可能出现交错的情况,导致数据输出顺序不一致。concatMap正好跟flatMap相反。switchMap在发射数据的时候,只会发射最新的数据,放弃旧的数据。如果还看不懂多演练几遍,体会一下,一般都能达到事半功倍的效果。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。