RxJava2实战---第五章 变换操作符和过滤操作符
RxJava的变换操作符主要包括以下几种:
-
map():对序列的每一项都用一个函数来变换Observable发射的数据序列。
-
flatMap()、concatMap()和flatMapIterable():将Obsrvable发射的数据集合变换为Observables集合,让后将这些Observable发射的数据平坦化地放进一个单独的Observable中。
-
switchMap():将Observable发射的数据集合变换为Observables集合,然后只发射这些Observables最近发射过得数据。
-
scan():对Observable发射的每一项数据应用一个函数,然后按顺序依次发射每一个值。
-
groupBy():将Observable拆分为Observable集合,将原始Obsrevable发射的数据按Key分组,每一个Observable发射过一组不同的数据。
-
buffer():定期从Observable收集数据到一个集合,然后把这些数据集合打包发射,而不是依次发射一个。
-
window():定期将来自Observable的数据拆分成一些Observable窗口,然后发射这些窗口,而不是每次发射一项。
-
cast():在发射之前强制将Observable发射的所有数据转换为指定类型。
Rxjava的过滤操作符主要包括以下几种:
- fileter():过滤数据。
- takeLast():只发射最后的N项数据。
- last():只发射最后一项数据。
- lastOrDefault():只发射最后一线数据,如果Observable为空,九发射默认值。
- takeLastBuffer():将最后的N项数据当做当个数据发射。
- skip():跳过开始的N项数据。
- skipLast():跳过最后的N项数据。
- take():只发射开始的N项数据。
- first() and takeFirst():只发射第一项数据,或者满足某种条件的第一项数据。
- firstOrDefault():只发射第一项数据,如果Obsrvable为空,就发射默认值。
- elementAt():发射第N项数据。
- elementAtOrDefault():发射第N项数据,如果Observable数据少于N项,就发射默认值。
- sample() or throttleLast(): 定期发射Observable最近的数据。
- throttleFirst():定期发射Observable发射的第一项数据。
- throttleWithTimeout() or debounce():只有当Observable在指定的时间段后还没有发射数据时,才发射一个数据。
- timeout():如果在一个指定的时间段后还没发射数据,就发射一个异常。
- distinct():过滤掉重复的数据。
- distinctUntilChanged():过滤连续重复的数据。
- ofType():只发射指定类型的数据。
- ignoreElements():丢弃所有的正常数据,只发射错误或完成通知。
1. map、flatMap、concatMap、flatMapIterable和SwitchMap()
1.1 map操作符
map操作符对原始Observable发射的每一项数据应用一个函数,然后返回一个发射这些结果的Observable。
Observable.just("HELLO")
.map(new Function<String, String>() {
@Override
public String apply(String s) throws Exception {
return s.toLowerCase();
}
})
.map(new Function<String, String>() {
@Override
public String apply(String s) throws Exception {
return s+" world!";
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
});
执行结果:
hello world!
1.2 flatMap操作符
flatMap将一个发射数据的Observable变换为多个Observables,然后将它们发射的数据合并后放进一个单独的Observable。
flatMap操作符使用一个指定的函数对原始Observable发射的每一项数据执行变换操作,这个函数返回一个本身也发射数据的Observable,然后flatMap合并这些Observables发射的数据,最后将合并后的结果当做自己的数据序列发射。 元素是无序的
案例:定义一个用户对象,包含用户名和地址:
public class User {
public String userName;
public List<Address> addresses;
public static class Address{
public String street;
public String city;
}
}
User user=new User();
user.userName="tony";
user.addresses=new ArrayList<>();
User.Address address1=new User.Address();
address1.street="ren ming road";
address1.city="Hang Zhou";
user.addresses.add(address1);
User.Address address2=new User.Address();
address2.street="dong xin da dao";
address2.city="Hang Zhou";
user.addresses.add(address2);
打印某个用户的所有地址。
使用map操作符:
Observable.just(user)
.map(new Function<User, List<User.Address>>() {
@Override
public List<User.Address> apply(User user) throws Exception {
return user.addresses;
}
})
.subscribe(new Consumer<List<User.Address>>() {
@Override
public void accept(List<User.Address> addresses) throws Exception {
for (User.Address address : addresses) {
System.out.println(address.street);
}
}
});
打印结果:
ren ming road
dong xin da dao
使用flatMap操作符:
Observable.just(user)
.flatMap(new Function<User, ObservableSource<User.Address>>() {
@Override
public ObservableSource<User.Address> apply(User user) throws Exception {
return Observable.fromIterable(user.addresses);
}
})
.subscribe(new Consumer<User.Address>() {
@Override
public void accept(User.Address address) throws Exception {
System.out.println(address.street);
}
});
执行结果:
ren ming road
dong xin da dao
1.3 concatmap()
ContactMap是用来解决FlatMap操作符,在转换数据的过程,会出现任务交叉的问题。如果,你对数据转换的过程,要求严格的按顺序执行。即执行完一个任务后,再执行另一个任务。那么,就用ContactMap替代FlatMap。用法一模一样,就换个名字而已。
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
Observable.fromIterable(list)
.flatMap(new Function<Integer, ObservableSource<String>>() {
@Override
public ObservableSource<String> apply(Integer integer) throws Exception {
String s="第"+integer+"个";
return Observable.just(s);
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
});
执行结果:
第1个
第2个
第3个
第4个
第5个
第6个
1.4 flatMapIterable()
flatMapIterable操作与flatMap,在流程上,大体都相同。唯一不同的是,flatMap是转一个Observable 转换成多个Observables。每一个Observable,最后又得返回一个Observable。而flatMapIterable在将一个Observable转换成多个Observables后,每一个Observable,只能返回一个Iterable。而不是另一个Observable。。。 Iterable,可以理解成返回一个list。
List<Integer> list=new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
list.add(6);
Observable.fromIterable(list)
.flatMapIterable(new Function<Integer, Iterable<String>>() {
@Override
public Iterable<String> apply(Integer integer) throws Exception {
System.out.println("onNext:");
return Arrays.asList("a"+integer,"b"+integer,"c"+integer);
}
})
.subscribe(new Consumer<String>() {
@Override
public void accept(String s) throws Exception {
System.out.println(s);
}
});
执行结果:
onNext:
a1
b1
c1
onNext:
a2
b2
c2
onNext:
a3
b3
c3
onNext:
a4
b4
c4
onNext:
a5
b5
c5
onNext:
a6
b6
c6
1.5 switchMap()
当上一个任务尚未完成时,就开始下一个任务的话,上一个任务就会被取消掉。如果,都是在同一个线程里跑的话。那么,这个操作符与contachMap()就无异了,都是先跑的先到。只有在不同的线程里跑的时候,即线程方案为newThread的时候。
同一线程:
Observable.just("A", "B", "C", "D", "E").switchMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String s) {
Observable<String> ob = Observable.just(s);
return ob;
}
}).subscribeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<String>() {
@Override
public void onCompleted() {
LogUtils.d("------>onCompleted()");
}
@Override
public void onError(Throwable e) {
LogUtils.d("------>onError()" + e);
}
@Override
public void onNext(String s) {
LogUtils.d("------>onNext:" + s);
}
});
执行结果:
02-26 17:10:28.878 28598-28598/com.rxandroid.test1 D/----->: ------>onNext:A
02-26 17:10:28.878 28598-28598/com.rxandroid.test1 D/----->: ------>onNext:B
02-26 17:10:28.878 28598-28598/com.rxandroid.test1 D/----->: ------>onNext:C
02-26 17:10:28.878 28598-28598/com.rxandroid.test1 D/----->: ------>onNext:D
02-26 17:10:28.878 28598-28598/com.rxandroid.test1 D/----->: ------>onNext:E
02-26 17:10:28.878 28598-28598/com.rxandroid.test1 D/----->: ------>onCompleted()
不同线程:
Observable.just("A", "B", "C", "D", "E").switchMap(new Func1<String, Observable<String>>() {
@Override
public Observable<String> call(String s) {
return Observable.just(s).subscribeOn(Schedulers.newThread());
}
}).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<String>() {
@Override
public void onCompleted() {
LogUtils.d("------>onCompleted()");
}
@Override
public void onError(Throwable e) {
LogUtils.d("------>onError()" + e);
}
@Override
public void onNext(String s) {
LogUtils.d("------>onNext:" + s);
}
});
执行结果:
02-26 17:19:17.138 4980-4980/com.rxandroid.test1 D/----->: ------>onNext:E
02-26 17:19:17.138 4980-4980/com.rxandroid.test1 D/----->: ------>onCompleted()
2. groupBy
groupBy操作符将一个Observable拆分成一些Observable集合,他们中的每一个都发射原始Observable的一个子序列。
哪个数据项由哪一个Observable发射是由一个函数判定的,这个函数给每一项指定一个Key,Key相同的数据会被同一个Observable发射。
最终返回的是Observable的一个特殊子类GroupedObservable。它是一个抽象类。getKey()方法是GroupedObservable的方法,这个Key用于将数据分组到指定的Observable。
示例:
Observable.range(1,8).groupBy(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return (integer%2==0)?"偶数组":"奇数组";
}
}).subscribe(new Consumer<GroupedObservable<String, Integer>>() {
@Override
public void accept(GroupedObservable<String, Integer> stringIntegerGroupedObservable) throws Exception {
System.out.println("group name:"+stringIntegerGroupedObservable.getKey());
}
});
执行结果:
group name:奇数组
group name:偶数组
选出奇数组的GroupedObservable,最后打印出该GroupedObservable下的全体成员:
Observable.range(1,8).groupBy(new Function<Integer, String>() {
@Override
public String apply(Integer integer) throws Exception {
return (integer%2==0)?"偶数组":"奇数组";
}
}).subscribe(new Consumer<GroupedObservable<String, Integer>>() {
@Override
public void accept(GroupedObservable<String, Integer> stringIntegerGroupedObservable) throws Exception {
if(stringIntegerGroupedObservable.getKey().equalsIgnoreCase("奇数组")){
stringIntegerGroupedObservable.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
});
}
}
});
执行结果:
1
3
5
7
3. buffer和window
3.1 buffer操作符
buffer会定期收集Observable数据并放进一个数据包裹,而不是一次发射一个值。
buffer操作符将一个Observable变换为另一个,原来的Observable正常发射数据,由变换产生的Observable发射这些数据的缓存集合。
示例代码:
Observable.range(1,10)
.buffer(2)
.subscribe(new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integers) throws Exception {
System.out.println(integers);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
执行结果:
[1, 2]
[3, 4]
[5, 6]
[7, 8]
[9, 10]
onComplete
buffer的重载方法:buffer(count,skip):
buffer(count,skip)从原始Observable的第一项数据开始创建新的缓存,此后每当收到skip项数据,就用count项数据填充缓存:开头的一项和后续的count-1项。它以列表(List)的形式发射缓存,这些缓存可能会有重叠部分(比如skip<count时),也有可能会有间隙(比如skip>count时),取决于count和skip的值。
Observable.range(1,11)
.buffer(5,1)
.subscribe(new Consumer<List<Integer>>() {
@Override
public void accept(List<Integer> integers) throws Exception {
System.out.println(integers);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
执行结果:
[1, 2, 3, 4, 5]
[2, 3, 4, 5, 6]
[3, 4, 5, 6, 7]
[4, 5, 6, 7, 8]
[5, 6, 7, 8, 9]
[6, 7, 8, 9, 10]
[7, 8, 9, 10, 11]
[8, 9, 10, 11]
[9, 10, 11]
[10, 11]
[11]
onComplete
如果原来的Observable发射了一个onError通知,那么buffer会立即传递这个通知,而不是首先发射缓存的数据,即使在这之前缓存中包含了原始Obsrvable发射的数据。
window操作符与buffer类似,但它发射之前是把收集到的数据放进单独的Observable,而不是放进一个数据结构。
3.2 window操作符
定期将来自原始Observable的数据分解为一个Observable窗口,发射这些窗口,而不是每次发射一项数据。
window发射的不是原始Observable的数据包,而是Observables,这些Observables中每一个都发射原始Observable数据的一个子集,最后发射一个onComplete通知。
Observable.range(1,11)
.window(2)
.subscribe(new Consumer<Observable<Integer>>() {
@Override
public void accept(Observable<Integer> integerObservable) throws Exception {
System.out.println("onNext:");
integerObservable.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println("accept:"+integer);
}
});
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
执行结果:
onNext:
accept:1
accept:2
onNext:
accept:3
accept:4
onNext:
accept:5
accept:6
onNext:
accept:7
accept:8
onNext:
accept:9
accept:10
onNext:
accept:11
onComplete
4. scan()和cast()
4.1 scan 操作符
scan(BiFunction<T, T, T> accumulator)
连续地对数据序列的每一项应用一个函数,然后连续发射结果
Scan操作符对原始Observable发射的第一项数据应用一个函数,然后将那个函数的结果作为自己的第一项数据发射。它将函数的结果同第二项数据一起填充给这个函数来产生它自己的第二项数据。它持续进行这个过程来产生剩余的数据序列。这个操作符在某些情况下被叫做accumulator
Observable.just(1,2,3,4,5)
.scan(new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) throws Exception {
System.out.println("integer:"+integer+" integer2:"+integer2);
return integer+integer2;
}
})
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
});
//使用lambda表达式简化:
Observable.just(1,2,3,4,5)
.scan(((integer, integer2) -> {
System.out.println("integer:"+integer+" integer2:"+integer2);
return integer+integer2;
}))
.subscribe(integer -> System.out.println(integer));
执行结果:
1
integer:1 integer2:2
3
integer:3 integer2:3
6
integer:6 integer2:4
10
integer:10 integer2:5
15
scan(final R initialValue, BiFunction<R, ? super T, R> accumulator)
R参数的意思是将其当做一个基值,让后续的值去累加计算。
有一个scan操作符的变体,你可以传递一个种子值给累加器函数的第一次调用(Observable发射的第一项数据)。如果你使用这个版本,scan将发射种子值作为自己的第一项数据。注意:传递null作为种子值与不传递是不同的,null种子值是合法的。
这个操作符默认不在任何特定的调度器上执行。
Observable.just(1,2,3,4,5)
.scan(10,new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) throws Exception {
System.out.println("integer:"+integer+" integer2:"+integer2);
return integer+integer2;
}
})
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
});
//使用lambda表达式简化:
Observable.just(1,2,3,4,5)
.scan(10,(integer, integer2) -> {
System.out.println("integer:"+integer+" integer2:"+integer2);
return integer+integer2;
})
.subscribe(integer -> System.out.println(integer));
执行结果:
10
integer:10 integer2:1
11
integer:11 integer2:2
13
integer:13 integer2:3
16
integer:16 integer2:4
20
integer:20 integer2:5
25
4.2 cast操作符
cast操作符就是将不同数据类型转换成指定类型.
Observable.just(1.0f,2.0f,3.0f,4.0f,5.0f)
.cast(Number.class)
.subscribe(new Consumer<Number>() {
@Override
public void accept(Number s) throws Exception {
System.out.println(s);
}
});
执行结果:
1.0
2.0
3.0
4.0
5.0
5.first和last
5.1 first操作符
只发射第一项(或者满足某个条件的第一项)数据
在RxJava2.x中,使用first()需要一个默认的Item ,对于Observable而言,使用了first()会返回Single类型。
Observable.just(1,2,3)
.first(1)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
});
执行结果:
1
如果Observable不发射任何数据,那么first操作符的默认值就起了作用
Observable.<Integer>empty()
.first(2)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
});
执行结果:
2
其他的first相关操作符:
- firstElement(): 表示只取第一个数据,没有默认值。
- firstOrError(): 表示要么能取到第一个数据,要么执行onError方法,他们分别返回Maybe类型和Single类型
5.2 last操作符
只发射最后一项(或者满足某个条件的最后一项)数据。
last操作符和first操作符类似,需要一个默认的Item,也是返回Single类型。
Observable.just(1,2,3)
.last(4)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
});
执行结果:
3
与last相关的操作符:lastElement,lastOrError
6. take和takeLast
6.1 take操作符
take(n):只发射前面的n项数据。
使用take操作符可以只修改Observable的行为,返回前面的n项数据,发射完成通知,忽略剩余的数据。
Observable.just(1,2,3,4,5)
.take(3)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
});
执行结果:
1
2
3
如果对一个Observable使用take(n)操作符,而那个Observable发射的数据少于n项,那么take操作符生成的Observable就不会抛出异常或者发射onError通知,而是仍然会发射那些数据。
Observable.just(1,2,3,4,5)
.take(6)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
});
执行结果:
1
2
3
4
5
重载方法:take(long time, TimeUnit unit)
只发射前面指定时间段内的发射的数据。
Observable.intervalRange(0,10,1,1,TimeUnit.SECONDS)
.take(3001,TimeUnit.MILLISECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
System.out.println(aLong);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
执行结果:
0
1
2
onComplete
6.2 takeLast操作符
发射Observable发射的最后n项数据。
使用takeLast操作符可以只修改原始Observable,只发射Observable发射的最后n项数据,忽略前面的数据。
如果对一个Observable使用takeLast(n)操作符,而那个Observable发射的数据少于n项,那么takeLast操作符生成的Observable就不会抛出异常或者发射onError通知,而是仍然会发射那些数据。
Observable.just(1,2,3,4,5)
.takeLast(3)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
执行结果:
3
4
5
重载方法:takeLast(long time, TimeUnit unit)
发射在原始Observable生命周期内最后指定时间段内发射的数据。
Observable.intervalRange(0,10,1,1,TimeUnit.SECONDS)
.takeLast(3,TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
System.out.println(aLong);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
执行结果:
7
8
9
onComplete
7. skip和skipLast
7.1 skip操作符
skip(long count)
跳过Observable发射的前n项数据,只保留后面的数据。
Observable.just(1,2,3,4,5)
.skip(3)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
执行结果:
4
5
onComplete
skip(long time, TimeUnit unit)
丢弃开始指定时间段内发射的数据。
Observable.interval(1,TimeUnit.SECONDS)
.skip(3,TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
System.out.println(aLong);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
执行结果:
3
4
5
6
7
8
9
7.2 skipLast操作符
skipLast(long count)
跳过Observable发射的最后n项数据,只保留前面发射的数据。
Observable.just(1,2,3,4,5)
.skipLast(3)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
执行结果:
1
2
onComplete
skipLast(long time, TimeUnit unit)
丢弃最后指定时间段内发射的数据。
Observable.interval(1,TimeUnit.SECONDS)
.skipLast(3,TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
System.out.println(aLong);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
执行结果:
0
1
2
3
4
5
6
8. elementAt和ignoreElements
8.1 elementAt操作符
elementAt(long index)
只发射第 index 项数据
如果原始Observable的数据小于index+1,那么会调用onComplete()方法。
返回一个Maybe类型
Observable.just(1,2,3,4,5)
.elementAt(2)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
打印结果:
3
如果上面的elementAt(2)改为elementAt(10):
打印结果:onComplete
elementAt(long index, T defaultItem)
只发射第 index 项数据
如果原始Observable的数据小于index+1,那么取默认值 defaultItem。
返回一个Single类型
Observable.just(1,2,3,4,5)
.elementAt(10,0)
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
});
打印结果:
0
8.2 ignoreElements操作符
不发射任何数据,只发射Observable的终止通知。返回一个Completable类型。
Observable.just(1,2,3,4,5)
.ignoreElements()
.subscribe(new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
});
执行结果:
onComplete
9. distinct和filter
9.1 distinct操作符
过滤掉重复的数据项
Observable.just(1,2,3,1,2,3,5,4,5,6)
.distinct()
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
执行结果:
1
2
3
5
4
6
onComplete
distinct(Function<? super T, K> keySelector)
根据原始Observable发射的数据项产生一个key,然后,比较这些Key而不是数据本身,来 判定两个数据是否不同
distinctUntilChanged()
判断一个数据是否和前一个数据是否相同
Observable.just(1,2,2,2,4,2,2,3,3,4)
.distinctUntilChanged()
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
执行结果:
1
2
4
2
3
4
onComplete
9.2 filter操作符
指定一个谓词函数测试数据项,发射 通过测试的数据。
Observable.just(1,20,23,76,7,81,2)
.filter(new Predicate<Integer>() {
@Override
public boolean test(Integer integer) throws Exception {
return integer>10;
}
})
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
执行结果:
20
23
76
81
onComplete
10. debounce
仅在过了一段指定的时间还没发射数据时才发射一个数据
debounce操作符会过滤掉发射速率过快的数据项
Observable.create(new ObservableOnSubscribe<Integer>() {
@Override
public void subscribe(ObservableEmitter<Integer> emitter) throws Exception {
if(emitter.isDisposed()) return;
try {
for (int i = 1; i <11 ; i++) {
emitter.onNext(i);
Thread.sleep(i*100);
}
emitter.onComplete();
}catch (Exception e){
emitter.onError(e);
}
}
}).debounce(500,TimeUnit.MILLISECONDS)
//如果发射数据间隔少于500ms,就过滤拦截
.subscribe(new Consumer<Integer>() {
@Override
public void accept(Integer integer) throws Exception {
System.out.println(integer);
}
}, new Consumer<Throwable>() {
@Override
public void accept(Throwable throwable) throws Exception {
System.out.println("onError");
}
}, new Action() {
@Override
public void run() throws Exception {
System.out.println("onComplete");
}
});
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
执行结果:
6
7
8
9
10
onComplete
12 sample()
定期发射Observable最近发射的数据项,Sample
操作符定时查看一个Observable,然后发射自上次采样以来它最近发射的数据。
Observable.interval(1,TimeUnit.SECONDS)
.sample(2,TimeUnit.SECONDS)
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
System.out.println(aLong);
}
});
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
执行结果:
0
2
4
6
8
注意这里会默认开启一个新线程,我们也可以指定线程
Observable.interval(1,TimeUnit.SECONDS)
.sample(2,TimeUnit.SECONDS, Schedulers.newThread())
.subscribe(new Consumer<Long>() {
@Override
public void accept(Long aLong) throws Exception {
System.out.println(aLong);
}
});
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
执行结果:
0
2
4
6
8
13 throttleLast、throttleFirst和throttleWithTimeout()
13.1 throttleLast
在一个指定的时间间隔里由Observable发射最近一次(最后一次)的数值。 和sample一样,只是名称不同
//调用sample()
public final Observable<T> throttleLast(long intervalDuration, TimeUnit unit) {
return sample(intervalDuration, unit);
}
public final Observable<T> sample(long period, TimeUnit unit) {
return sample(period, unit, Schedulers.computation());
}
13.2 throttleFirst
throttleFirst
与throttleLast/sample
不同,在每个采样周期内,它总是发射原始Observable的第一项数据,而不是最近的一项。
13.3 throttleWithTimeout()
每产生一个数据后,如果在规定的间隔时间内没有别的数据产生,就会发射这个数据,否则忽略该数据。
throttleWithTimeout 和 debounce 作用一样,通过源码可以看到,它也是调用的 debounce:
根据指定的时间间隔进行限流,时间单位通过TimeUnit
参数指定。这种操作符默认在computation
调度器上执行,但是你可以通过第三个参数指定。
11 小结
变换操作符的作用是对被观察者发射的数据按照一定规则做一些变换操作,然后将变换后的数据发射出去。
过滤操作符的作用是过滤掉被观察者发射的一些数据,不让它们发射出去,也就是忽略与丢弃。至于需要过滤哪些数据,则需要按照不同的规则来进行。