RxJava-变换操作符
- 对事件序列中的事件 / 整个事件序列 进行加工处理(即变换),使得其转变成不同的事件 / 整个事件序列
- 还是直接看代码效果吧
变换操作符1:map
- 对 被观察者发送的每1个事件都通过 指定的函数 处理,从而变换成另外一种事件
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).map(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return "使用map操作符将Integer类型的事件 "+integer +" 变成String类型";
}
}).subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
Log.d(TAG, "accept: 消息是String类型的 == " + s );
}
});
消息是String类型的 == 使用map操作符将Integer类型的事件 1 变成String类型
消息是String类型的 == 使用map操作符将Integer类型的事件 2 变成String类型
消息是String类型的 == 使用map操作符将Integer类型的事件 3 变成String类型
- 可以看到,在创建被观察者和订阅观察者之间,增加了一个map方法,使得我们一开始创建的整型类型的时间通过map方法中我们自己编写的逻辑,将他变成了字符串类型
- 当然不只是从整型转字符串,只要泛型支持,我们都可以去转换
变换操作符2:FlatMap
- 将被观察者发送的事件序列进行 拆分 & 单独转换,再合并成一个新的事件序列,最后再进行发送
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
emitter.onNext(1);
emitter.onNext(2);
emitter.onNext(3);
}
}).flatMap(new Function<Integer, ObservableSource<?>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
final List<String> list = new ArrayList<>();
list.add("我是事件 " + integer);
return Observable.fromIterable(list);
}
}).subscribe(new Consumer<Object>() {
@Override
public void accept(Object o) throws Exception {
Log.d(TAG, "accept: == " + (String) o) ;
}
});
accept: == 我是事件 1
accept: == 我是事件 2
accept: == 我是事件 3
- 这个方法不看源码的话着实对他的机制很难猜测,经过了一系列的实验,我大概说说我的理解吧
- 中间调用的flatMap方法其实是不影响自身与观察者的订阅时机的,也就是说,不管你中间加不加这个方法,我订阅的时机(也就是观察者的Subscriber方法执行的时间)是不会变的
- 那么中间的这个FlatMap方法在这里的主要工作是干什么呢,只不过在每次观察者接收到消息前先经过FlatMap这个方法,然后FlatMap这个方法再将消息处理之后再给观察者的onNext 方法
- 可以看到我在FlatMap方法里面只写了两句话,创建新的ArrayList,添加数据,重新发送出去
- 大概的顺序是,被观察者的subscribe方法->观察者的onSubscribe方法->被观察者的subscribe里面具体的第一条onNext语句,然后FlatMap的方法拦截,处理,重新发送->观察者的onNext方法
- 具体的使用细节,还是在用的时候具体实验吧
- 这里又说这个方法最终产生的消息顺序是无序的,也就是说不是按照原来的序列,不过我试了好几次都没发现
变换操作符3:ConcatMap
- 使用方法与上个FlatMap完全相同,在用法上只是说新产生的消息序列与原来序列相同
变换操作符4:Buffer
- 定期从 被观察者(Obervable)需要发送的事件中 获取一定数量的事件 & 放到缓存区中,最终发送
Observable.just(1,2,3,4,5,6,7)
.buffer(4,4)
.subscribe(new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integers) throws Exception {
Log.d(TAG, "accept: " + integers.toString());
}
});
accept: [1, 2, 3, 4]
accept: [5, 6, 7]
- 所以,两个参数的意思表示,第一个参数表示缓存区的大小是4,最多只能存四个,第二个参数表示从发来的事件序列中读取四次,然后一次性发送的观察者的onNext方法,注意这里第二个参数是读取的次数,而不代表就一定能读取到缓存区,如果缓存区没空间了,那么他的那一次读取是没有存到数据的
- 同样,这个方法还有好多个重载方法,这里我们常用的就这个和一个参数的,一个参数直接表示缓存区的大小,也就是缓存区满了就直接一次性发送
总结
- 简单来说,操作符的用法就是使我们之前的消息队列经过一层我们人为的过滤,或者说处理,使得更为我们所更好的利用