學習資料
1.過濾操作符
作用:對Observable發射的 數據序列 進行 過濾或選擇
1.1 first
只發射第一個或者第一個滿足某個條件的數據項
1.1.1 first()第一項
簡單使用:
public class FirstDemo {
public static void main(String[] args) {
first();
}
/**
* 只發送第一項數據
*/
private static void first() {
Observable
.just(1,2,3,4)
.first()
.subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println(integer);
}
});
}
}
運行結果:
1
1.1.2 first(Func1)
只發送第一個滿足條件的數據
簡單使用:
/**
* 第一個偶數
*/
private static void firstTrue() {
Observable
.just(1,3,4,5)
.first(new Func1<Integer, Boolean>() {
@Override
public Boolean call(Integer integer) {
return integer % 2 == 0;
}
})
.subscribe((i)->System.out.println("第一個偶數:" + i));
}
運行結果:
第一個偶數:4
last
正好與first
相反,是只發送最后一個或者最后一個滿足條件的數據項
1.2 take
只發送前N項數據
1.2.1 take(int)
只發送前int
項數據項,默認不任何特定的調度器上執行
簡單使用:
/**
* 只發送前5項數據
*/
private static void takeInt() {
Observable
.interval(500, TimeUnit.MILLISECONDS, Schedulers.immediate())
.take(5)
.subscribe((i) -> System.out.print(i + " ,"));
}
運行結果:
0 ,1 ,2 ,3 ,4 ,
1.2.2 take(long,TimeUnit,Scheduler)
在寫定的時間段內,會發送Observable
發出的數據項,默認在computation
運算調度器上執行
簡單使用:
/**
* 發送1s以內的數據項
*/
private static void takeTime() {
Observable
.interval(100, TimeUnit.MILLISECONDS, Schedulers.immediate())
.take(1,TimeUnit.SECONDS ,Schedulers.newThread())
.subscribe((i) -> System.out.print(i + " ,"));
}
運行結果:
0 ,1 ,2 ,3 ,4 ,5 ,6 ,7 ,8 ,
發送的數據項只是1s以內的,并不包括1s時的
takeLast
是只發送后n
項數據
1.3 Skip
跳過數據項
1.3.1 skip(int)
跳過Observable
發送的前n項數據項,默認不在任何特定的調度器上執行
簡單使用:
/**
* 跳過前3項數據
*/
private static void skipInt() {
Observable
.range(1,10)
.skip(3)
.subscribe((i) -> System.out.print(i + " ,"));
}
運行結果:
4 ,5 ,6 ,7 ,8 ,9 ,10 ,
1.3.2 skip(long,TimeUnit,Scheduler)
跳過給定的時間段內Obsvable
發送過來的數據項,默認在computation
運算調度器上執行
簡單使用:
/**
* 發送前5個,500毫秒之后的數據項
*/
private static void skipTime() {
Observable
.interval(100, TimeUnit.MILLISECONDS, Schedulers.immediate())
.skip(500,TimeUnit.MILLISECONDS)
.take(5)
.subscribe((i) -> System.out.print(i + " ,"));
}
運行結果:
4 ,5 ,6 ,7 ,8 ,
SkipLast
就是跳過后n個數據項
1.4 Sample
定期發射Observable
最近發射的數據項
1.4.1 sample(long,TimeUnit)
定時查看一個Observable
,然后將自上次采樣后,Observable
最近一次發送的數據發送出去,默認在默認在computation
調度器上執行
注意:如果從上次采樣后,原始的Observable
沒有發出數據項,sample
操作返回的新的Observable
在監測期時間內也不會發射任何數據
簡單使用:
/**
* 每隔100毫秒,將Observable最近一個發送的數據項發送出去
*/
private static void sampleTime() {
Observable
.interval(30,TimeUnit.MILLISECONDS, Schedulers.immediate())
.sample(100, TimeUnit.MILLISECONDS)
.take(5)
.subscribe((i) -> System.out.print(i + " ,"));
}
運行結果:
1 ,5 ,8 ,11 ,15 ,
1.4.2 sample(Observable)
- sample(signal)
當監測到名字為signal
的Obaervable
發過來一個信號或者終止時,就對原始Observable
發送的數據進行采樣,然后將自從上次采樣以來最近一次發送的數據發送出去
默認不在任何特定的調度器上執行
簡單使用:
/**
* 每當收到信號時,將最近發送的一個數據項發送出去
*/
private static void sameSignal() {
Observable
.interval(30,TimeUnit.MILLISECONDS, Schedulers.immediate())
.sample(Observable.interval(100,TimeUnit.MILLISECONDS))
.take(5)
.subscribe((i) -> System.out.print(i + " ,"));
}
運行結果:
2 ,5 ,8 ,12 ,15 ,
第一個輸出的數字是2,因為是從0開始的,每次輸出的數字中間都會間隔2個
1.5 Debounce
兩次發送數據項間隔大于一段指定的時間,才發射一個數據
注意:最后的onCompleted
信號,會緊隨著最后一項原始Observable
數據項,即使是小于時間間隔,一旦結束到onCompleted
信號,整個操作也就結束了,onCompleted
通知不會觸發限流
1.5.1 debounce(long,TimeUnit)
在指定的時間long
間隔進行限流,個人理解,過濾兩次數據小于指定間隔的數據項,與上次發送的時間差大于間隔的數據項才進行發送
默認在computation
調度器上執行
簡單使用:
/**
* 輸出兩次間隔大于150秒的數據項
*/
private static void deBounceTime() {
Observable
.create(new Observable.OnSubscribe<Integer>() {
@Override
public void call(Subscriber<? super Integer> subscriber) {
try {
for (int i = 0; i < 5; i++) {
//產生在100到200間隨機時間間隔
TimeUnit.MILLISECONDS.sleep((int) (Math.random() * 100 + 100));
subscriber.onNext(i);
}
//延遲結束信號 否則最后一次一定不會發送
TimeUnit.MILLISECONDS.sleep(100);
subscriber.onCompleted();
} catch (InterruptedException e) {
subscriber.onError(e);
}
}
})
.debounce(150, TimeUnit.MILLISECONDS, Schedulers.newThread())
.subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
System.out.println(" --> onCompleted");
}
@Override
public void onError(Throwable e) {
System.out.println(e.getMessage());
}
@Override
public void onNext(Integer integer) {
System.out.print(integer + " ,");
}
});
}
運行結果:
2 ,4 , --> onCompleted
注意subscriber.onCompleted()
發送結束通知信號的時機
1.5.2 debounce(Func1)
對原始Observable
的每一個數據項應用一個函數進行限流,這個函數返回一個Observable
。接到通知前,原始Observable發送的數據項將會被抑制
默認不在任何特定的調度器上執行
簡單使用:
/**
* 在沒有接到通知的150毫秒內,原始Observable發送的數據項將會被抑制
*/
private static void deBounceSignal() {
Observable
.create((subscriber) -> {
try {
for (int i = 0; i < 5; i++) {
//產生在100到200間隨機時間間隔
TimeUnit.MILLISECONDS.sleep((int) (Math.random() * 100 + 100));
subscriber.onNext(i);
}
//延遲結束信號 否則最后一次一定不會發送
TimeUnit.MILLISECONDS.sleep(100);
subscriber.onCompleted();
} catch (InterruptedException e) {
subscriber.onError(e);
}
})
.debounce(new Func1<Object, Observable<Long>>() {
@Override
public Observable<Long> call(Object o) {
//每隔150毫秒發出一個通知
return Observable.interval(150, TimeUnit.MILLISECONDS);
}
})
.subscribe(new Subscriber<Object>() {
@Override
public void onCompleted() {
System.out.println(" --> onCompleted");
}
@Override
public void onError(Throwable e) {
System.out.println(e.getMessage());
}
@Override
public void onNext(Object o) {
System.out.print(o + " ,");
}
});
}
運行結果:
0 ,2 ,4 , --> onCompleted
注意:最后一個數據項一定會被發送,即使在沒有接到通知的150毫秒內
1.6 Distinct
過濾掉重復的數據項,默認不在任何特定的調度器上執行
1.6.1 distinct()
簡單使用:
/**
* 去除重復項
*/
private static void distinct() {
Observable
.just(1,2,2,3,4,4,5,6,6)
.distinct()
.subscribe((i) -> System.out.print(i+" ,"));
}
運行結果:
1 ,2 ,3 ,4 ,5 ,6 ,
1.6.2 distinct(Func1)
將原始Observable
發送的數據項應用一個函數,根據這個函數產生不同的key
,之后的數據項便是比較key
,而不再管數據項
簡單使用:
/**
* 根據條件指定過濾的key ,將之后出現 key為"1","2",全部過濾
*/
private static void distinctKey() {
Observable
.just(1,2,2,3,3,4,5,6,6)
.distinct(new Func1<Integer, String>() {
@Override
public String call(Integer integer) {
//設置key
return integer / 2 == 0 ? "1" : "2" ;
}
})
.subscribe((i) -> System.out.print(i+" ,"));
}
運行結果:
1 ,2 ,
1.7 ElementAt
只發射索引值為N的數據項,索引從0開始
如果傳遞的索引為負數,或者索引不小于數據項個數,將會拋出一個IndexOutOfBoundsException
異常
簡單使用:
public class ElementAtDemo {
/**
* 輸出索引值為5的數據項,從0開始
*/
public static void main(String[] args) {
Observable
.range(1,10)
.elementAt(5)
.subscribe(System.out::println);
}
}
運行結果:
6
1.8 IgnoreElements
不發射任何數據,只發射Observable的終止通知onError
或onCompleted
若不關心Obsvable
發送的數據項,只想在完成時,或者遇到錯誤終止時收到通知,可以使用,這個操作符永遠不會調用觀察者的onNext()
方法
默認不在任何特定的調度器上執行
2. 最后
感覺過濾操作符比變換操作符理解起來要容易一些
本人很菜,有錯誤請指出
共鳴 :)