响应式编程包含一个Observable流、一个Subscriber,以及某种Subscription。该Subscription会传达Subscriber从Observable生产者处接收事件的意图。现在,是时候对流过响应式流的数据进行转换了。
1 基础操作符
操作符用于调整流的元素或更改流结构本身。虽然RxJava为几乎所有可能的场景提供了大量的操作符,将介绍最常用和最基础的操作符,因为大多数其他操作符只是这些基本操作符的组合。
1.1 map操作符:映射
<R> Observable<R> map(Func1<T, R> func)
可以将T对象类型转换为R对象类型, 将Observable<T>
转换为Observable<R>
public static void main(String[] args) {
Observable.just("java","python","go")
.map(String::toUpperCase)
.forEach(System.out::println);
}
JAVA
PYTHON
GO
1.2 filter操作符
public final Observable<T> filter(Func1<? super T, Boolean> predicate)
保留断言返回true的元素
public static void main(String[] args) {
Observable.just(1,2,3,4,5,6)
.filter(i-> i%2 == 0) // 保留偶数,所以经过filter之后,就剩下2 4 6
.forEach(System.out::println);
}
1.3 count操作符
返回输入流中的元素数量。
count操作符只在原始流结束时发出结果,因此,在处理无限流时,count操作符将不会完成或返回任何内容
public static void main(String[] args) {
Observable.just(1, 2, 3, 4, 5, 6) // 返回6
.count().forEach(System.out::println);
}
// 在处理无限流时,count操作符将不会完成或返回任何内容
public static void main(String[] args) {
Observable.interval(1, TimeUnit.MICROSECONDS)
.count().forEach(System.out::println); // 没有任何输出
}
1.4 zip操作符
zip函数来组合来自两个并行流的值。它通常用于填充数据,且特别适用于部分预期结果从不同源获取的情况
public static <R> Observable<R> zip(Iterable<? extends Observable<?>> ws, FuncN<? extends R> zipFunction)
public static <R> Observable<R> zip(Observable<?>[] ws, FuncN<? extends R> zipFunction)
public static <T1, T2, R> Observable<R> zip(Observable<? extends T1> o1, Observable<? extends T2> o2, final Func2<? super T1, ? super T2, ? extends R> zipFunction)
zip主要的三个重载方法就是上面三个:
- 接收一个可迭代的Observable
- 接收一个Observable数组
- 接收可变Observable
其实第三个把前两个的能力就包括了,只是前两个在某些场景下,
eg:
public static void main(String[] args) {
Observable.zip(
Observable.just("A","B","C"),
Observable.just("a","b"),
(String s1,String s2) ->{
return s1 + s2;
}
).forEach(System.out::println);
}
输出:
Aa
Bb
注意观察输出,在合并的时候,由于第二个Observable只有两个元素,所以舍弃了第一个Observable的C元素
还提供了一个非静态方法zipWith,功能是一样的:
Observable.just("A","B","C").zipWith(Observable.just("a","b","c"),(s1,s2)->{
return s1 + s2;
}).forEach(System.out::println);
1.5 自定义操作符
也可以通过实现从Observable.Transformer<T,R>派生的类来编写自定义操作符。
通过应用Observable.compose(transformer)操作符,我们可以将这样的操作符逻辑包括在工作流中
public interface Transformer<T, R> extends Func1<Observable<T>, Observable<R>> {
// cover for generics insanity
}
public interface Func1<T, R> extends Function {
R call(T t);
}
演示:
public static void main(String[] args) {
Observable.Transformer transformer = new Observable.Transformer<Integer, String>() {
@Override
public Observable<String> call(Observable<Integer> integerObservable) {
return integerObservable.map(i-> "RX" + i );
}
};
Observable.just(1,2,3)
.compose(transformer).forEach(System.out::println);
}
使用lambda简化:
Observable.just(1,2,3)
.compose((input) -> input.map(i->"RX"+i))
.forEach(System.out::println);