变换操作符
map 装换对象的时候使用,就是把一个Observable装换为另外一个Observable,例子
Observable.just("A").map(new Func1<String, Integer>() {
@Override
public Integer call(String s) {
return s.hashCode();
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
}
});
从这个例子我们就可以看出,这里是把一个关于String的Observable变换为了一个关于Integer的Observable,最后让被观察者得到。
map适合的范围是1对1的装换,不适合一对多的装换。
flatMap 一对多的转换,他的一版使用场景就是,比如去除for循环(map也行),比如需要把从一个对象去除它包含的List子对象然后迭代等,例子:一个对象A中,包含了一个List
Observable.just(test).flatMap(new Func1<Test, Observable<String>>() {
@Override
public Observable<String> call(Test test) {
return Observable.from(test.list);
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.i(TAG, s+"---FlatMap");
}
});
使用Map是暂时无法做到这一点的,除非是在call内部使用一个for循环去做。
flatMap的图是:
concatMap 一个输出有序的Observable,他的用户跟flatMap差不多,只是,他是会按照顺序输出,flatMap不一定,这种情况是在你需要返回一个Observable对象的时候,他是通过异步去获取的,比如
Observable.from(test.list).flatMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String str) {
return Observable.just(str).subscribeOn(Schedulers.from(Executors.newFixedThreadPool(1)));
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
}
});
使用flatMap的话并不一定能保证顺序。在测试过程发现假如把Schedulers.from(Executors.newFixedThreadPool(1))替换为Schedulers.io()或者是Schedulers.newThread()等是顺序不会变的,目前还不知道为什么,就是使用自定义的线程池的时候会。
swichMap 同样是跟flatMap很类似,除了有一点,就是在异步环境下,当旧数据订阅没有完成,switchMap取消订阅和停止监视那个数据项产生的的Observable,比如下面
Observable.from(test.list).switchMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String s) {
return Observable.just(s).subscribeOn(Schedulers.newThread());
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
}
});
被监视的Observable是否取消决定于他是否已经被观察者得到,假如得到的话观察者是能看到这个值的,但是假如他没有被观察者得到,就会被取消订阅,并且不在被观察。
上面那个假如是写成
Observable.from(test.list).switchMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String s) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return Observable.just(s).subscribeOn(Schedulers.newThread());
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
}
});
就会得到所有的输出。
case 装换操作符,他是强制制定类型的装换,没有map那么灵活,而且,当不能装换的时候,会爆出ClassCastException,例子
Observable.just("A").cast(String.class).subscribe(new Action1<String>() {
@Override
public void call(String String) {
Log.i(TAG,String);
}
});
groupBy 分组 就是按照一种类型的key分组,例子如下
Observable.range(10,10).groupBy(new Func1<Integer, Integer>() {
@Override
public Integer call(Integer integer) {
//制定某种规则,这里是分为了三种
return integer % 3;
}
}).subscribe(new Action1<GroupedObservable<Integer, Integer>>() {
@Override
public void call(GroupedObservable<Integer, Integer> stringIntegerGroupedObservable) {
stringIntegerGroupedObservable.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.i(TAG, stringIntegerGroupedObservable.getKey() + "====" +integer.toString());
}
});
}
});
输出是:
08-31 23:54:55.437 17504-17504/com.example.user.testproject I/RxJavaTest: 1====10
08-31 23:54:55.437 17504-17504/com.example.user.testproject I/RxJavaTest: 2====11
08-31 23:54:55.437 17504-17504/com.example.user.testproject I/RxJavaTest: 0====12
08-31 23:54:55.437 17504-17504/com.example.user.testproject I/RxJavaTest: 1====13
08-31 23:54:55.437 17504-17504/com.example.user.testproject I/RxJavaTest: 2====14
08-31 23:54:55.437 17504-17504/com.example.user.testproject I/RxJavaTest: 0====15
再比如
Observable.just("A","A","B","AB","C","D").groupBy(new Func1<String,Boolean>() {
@Override
public Boolean call(String s) {
return s.contains("A");
}
}).subscribe(new Action1<GroupedObservable<Boolean, String>>() {
@Override
public void call(GroupedObservable<Boolean, String> stringGroupedObservable) {
stringGroupedObservable.subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.i(TAG, stringGroupedObservable.getKey() + "====" +s.toString());
}
});
}
});
输出是:
08-31 23:53:14.357 16194-16194/com.example.user.testproject I/RxJavaTest: true====A
08-31 23:53:14.357 16194-16194/com.example.user.testproject I/RxJavaTest: true====A
08-31 23:53:14.357 16194-16194/com.example.user.testproject I/RxJavaTest: false====B
08-31 23:53:14.357 16194-16194/com.example.user.testproject I/RxJavaTest: true====AB
08-31 23:53:14.357 16194-16194/com.example.user.testproject I/RxJavaTest: false====C
08-31 23:53:14.357 16194-16194/com.example.user.testproject I/RxJavaTest: false====D
其中stringGroupedObservable.getKey()是获得分组的依据的表示,之后的那个是值。
2.7 Scan 他的作用是连续对数据序列的每一项应用一个func,然后连续发射结果。例子
Observable.range(10,2).scan(new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer integer, Integer integer2) {
Log.i(TAG, integer +"==="+integer2);
return integer+integer2;
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.i(TAG, integer + "Subacriber");
}
});
结果是:
09-01 21:40:45.112 22400-22400/com.example.user.testproject I/RxJavaTest: 10Subacriber
09-01 21:40:45.112 22400-22400/com.example.user.testproject I/RxJavaTest: 10===11
09-01 21:40:45.112 22400-22400/com.example.user.testproject I/RxJavaTest: 21Subacriber
他的第一个值是不参与func2的操作,当然你也可以传递一个init值进入作为默认操作。他的第一个参数是上一次计算的结果传入,第二个参数是被观察的序列值,从2开始,第三个是返回类型,三者是类型一样的。使用一个默认的种子计算的,比如
Observable.range(10, 2).scan("A", new Func2<String, Integer, String>() {
@Override
public String call(String s, Integer integer) {
Log.i(TAG, s + "==" + integer);
return s + integer;
}
}).subscribe(new Action1<String>() {
@Override
public void call(String s) {
Log.i(TAG, s);
}
});
输出结果
09-01 21:44:51.572 27312-27312/? I/RxJavaTest: A
09-01 21:44:51.572 27312-27312/? I/RxJavaTest: A==10
09-01 21:44:51.572 27312-27312/? I/RxJavaTest: A10
09-01 21:44:51.572 27312-27312/? I/RxJavaTest: A10==11
09-01 21:44:51.572 27312-27312/? I/RxJavaTest: A1011
flatMapIterable 他的作用是处理一些复杂的数据,接受一个Observable之后,返回一个Iterable,然后,这个Iterable会依次的传递给下面一层或者是Observer,例子
List<String> list = new ArrayList<>();
list.add("A");
list.add("E");
list.add("K");
Observable.from(list).flatMapIterable(new Func1<String, Iterable<Integer>>() {
@Override
public Iterable<Integer> call(String s) {
return getIntegers(s);
}
private Iterable<Integer> getIntegers(String s) {
List<Integer> integers = new ArrayList<>();
integers.add((int) s.charAt(0)+1);
integers.add(s.charAt(0)+2);
return integers;
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
Log.i(TAG, integer +"==flatMapIterable");
}
});
输出
09-01 22:05:35.582 19199-19199/com.example.user.testproject I/RxJavaTest: 66==flatMapIterable
09-01 22:05:35.582 19199-19199/com.example.user.testproject I/RxJavaTest: 67==flatMapIterable
09-01 22:05:35.582 19199-19199/com.example.user.testproject I/RxJavaTest: 70==flatMapIterable
09-01 22:05:35.582 19199-19199/com.example.user.testproject I/RxJavaTest: 71==flatMapIterable
09-01 22:05:35.582 19199-19199/com.example.user.testproject I/RxJavaTest: 76==flatMapIterable
09-01 22:05:35.582 19199-19199/com.example.user.testproject I/RxJavaTest: 77==flatMapIterable
buffer 该操作符的作用是先计算一定量的结果,之后再去回调结果给下一个Observable或者是Observer,例子
Observable.just("A","B","C").buffer(2).subscribe(new Action1<List<String>>() {
@Override
public void call(List<String> strings) {
Log.i(TAG, strings +"==flatMapIterable");
}
});
结果就是
09-01 22:10:41.272 24829-24829/com.example.user.testproject I/RxJavaTest: [A, B]==flatMapIterable
09-01 22:10:41.272 24829-24829/com.example.user.testproject I/RxJavaTest: [C]==flatMapIterable
这个方法是按照顺序不重复,当然他还有很多重载的操作,比如
buffer(int count, int skip) // 一次缓存几个,之后每次跳过几个,按照顺序,重复,每次剔除最前面的
buffer(long timespan, long timeshift, TimeUnit unit)
buffer(long timespan, TimeUnit unit)// 每个多久,取出数据