这篇章主要介绍Rxjava的变换操作符
目录
Debounce
仅在过了一段指定的时间还没发射数据时才发射一个数据,Debounce
操作符会过滤掉发射速率过快的数据项。其实我也没理解它说啥。看下面代码:
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> observableEmitter) throws Exception {
observableEmitter.onNext(1);
Thread.sleep(200);
observableEmitter.onNext(2);
Thread.sleep(300);
observableEmitter.onNext(3);
Thread.sleep(302);
observableEmitter.onNext(4);
Thread.sleep(100);
observableEmitter.onNext(5);
Thread.sleep(420);
observableEmitter.onNext(6);//
}
}).debounce(300, TimeUnit.MILLISECONDS) // ThrottleWithTimeout与其功能一样
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer s) throws Exception {
System.out.println(s + "*");
}
});
结果:
3*
5*
就只有3和5发送后,后面睡眠时间超过300毫秒,所以就只有他们打印出来。
Distinct
distinct
过滤掉重复的数据项,这个是过滤全列表重复,为什么提醒是全列表呢,后面还有一个类似的操作符,先看这个的代码。
Observable.just(1, 2, 1, 1, 2, 3)
.distinct()
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer s) throws Exception {
System.out.println(s + "*");
}
});
结果:
1*
2*
3*
distinctUntilChanged
这个跟上面的区别就是过滤连续的重复,只要看代码结果就明白了
Observable.just(1, 2, 1, 1, 2, 3)
.distinctUntilChanged()
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer s) throws Exception {
System.out.println(s + "*");
}
});
结果:
1*
2*
1*
2*
3*
这操作符只会去掉连续重复的1,只让连续的1里面保留一个1。
distinct(Func1)
distinctUntilChanged也有类似的做法,里面放一个函数。主要是数据源是基本类型的时候,distinct可以帮我们自动进行过滤操作。但数据源不是基本类型,或者你想修改过滤规则,就可以填入自己写的Func1函数。函数要返回一个用于比较的基本类型。
Student[] students = {new Student("1"), new Student("2"), new Student("1"),new Student("1"), new Student("2"),new Student("3")};
Observable.fromArray(students)
.distinct(student -> student.getName())
.subscribe(student -> System.out.println(student.getName() + "*"));
结果:
1*
2*
3*
ElementAt
只发射第N项数据,代码如下:
Observable.just(1, 2, 3, 4, 5, 6)
.elementAt(3)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer s) throws Exception {
System.out.println(s + "*");
}
});
结果:
4*
结果一看就明白,不用我多说。elementAt越界会怎样。
Observable.just(1, 2, 3, 4, 5, 6)
.elementAt(8)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer s) throws Exception {
System.out.println(s + "*");
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Throwable {
System.out.println(throwable.getMessage() + "+");
}
});
上面的代码是没输出结果的,elementAt里面传8,已经超过我们的数据源的size,但也不会进异常。把elementAt改成elementAtOrError操作符,就会进入异常了。
elementAt还可以传入默认值,当越界的时候就会输出默认值,代码如下:
Observable.just(1, 2, 3, 4, 5, 6)
.elementAt(8,0)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer s) throws Exception {
System.out.println(s + "*");
}
});
结果:
0*
Filter
filter
简单一句,就写一个条件,符合你写的过滤条件,才会被输出
Observable.just(1, 2, 3, 4, 5, 6)
.filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) throws Throwable {
return integer <= 4;
}
})
.subscribe(integer -> System.out.println(integer+"*"));
结果:
1*
2*
3*
4*
ofType
ofType
是filter
操作符的一个特殊形式。它过滤一个Observable只返回指定类型的数据。总之就是过滤你数据源指定的类型,才能被输出
Person[] peoples = {new Student("aaa"), new Teacher("bbb"), new Student("ccc")};
Observable.fromArray(peoples)
.ofType(Student.class)
.subscribe(people -> System.out.println(((Student)people).getName()));
结果:
aaa
ccc
上面Student和Teacher类都继承Person类,然后结果只会输出Student类的名字
First
Observable.just(1,2,3)
.firstElement()
.subscribe(integer -> System.out.println(integer+"*"));
结果:
1*
其实firstElement效果就是上面elementAt(0),输出数据源第一个数据。但也会用越界的情况,比如数据源是空的,所有有个firstOrError跟elementAtOrError对应。也可以像elementAt填入默认值,如下:
Observable.empty()
.first(2)
.subscribe(integer -> System.out.println(integer+"*"));
结果:
2*
因为数据源为空,结果就会输出默认值2
IgnoreElements
简单一说,就是这个操作符会忽略所有onNext的操作,直接进onError或onComplete
Observable.create(new ObservableOnSubscribe<String>() {
@Override
public void subscribe(ObservableEmitter<String> observableEmitter) throws Exception {
observableEmitter.onNext("1");
observableEmitter.onComplete();
}
}).ignoreElements().subscribe(new Action() {
@Override
public void run() throws Throwable {
System.out.println("完成");
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Throwable {
System.out.println("异常");
}
});
结果:
完成
不过onNext传递什么数据,它也只会进onComplete。大家可能会说,你都不写onNext的action给它订阅当然不进onNext。不是我不想写,是你用了ignoreElements后,后面的订阅就只能是onComplete和onError
Last
Observable.just(1,2,3)
.lastElement()
.subscribe(integer -> System.out.println(integer+"*"));
结果:
3*
这个真的不多说了,就是跟first操作符相反,输出最后一个数据源,当然异常和默认值写法也一样。
Skip
跳过指定个数的数据源,输出之后剩下的数据
Observable.just(1,2,3,4,5,6)
.skip(3)
.subscribe(integer -> System.out.println(integer+"*"));
Observable.just(1,2,3,4,5,6)
.skipLast(3)
.subscribe(integer -> System.out.println(integer+"*"));
结果:
4*
5*
6*
1*
2*
3*
第一段代码输出4,5,6因为前面跳过了3个,而skipLast也好理解,就是从后面跳三个,所以结果是1,2,3。
skip和skipLast除了跳过个数,还可以跳过时间,如skip(3,TimeUnit.SECONDS),就是跳过前面3秒内的数据源,输出3秒后的数据。
Take
只发射前面N条数据,其实就是跟skip相反,skip跳过的那些就是take想发送的那些
Observable.just(1,2,3,4,5,6)
.take(3)
.subscribe(integer -> System.out.println(integer+"*"));
结果:
1*
2*
3*
看结果和结合我的描述,相信已经明白。当然对应的take也有takeLast操作符,也可以跳过时间。