- Map 對序列的每一項都應用一個函數來變換Observable發射的數據序列
- Cast 操作符將原始Observable發射的每一項數據都強制轉換爲一個指定的類型然後再發射數據它是map的一個特殊版本
- FlatMap 將Observable發射的數據集合變換爲Observables集合然後將這些Observable發射的數據平坦化的放進一個單獨的Observable
- ConcatMap 它類似於最簡單版本的flatMap但是它按次序連接而不是合併那些生成的Observables然後產生自己的數據序列
- SwitchMap 將Observable發射的數據集合變換爲Observables集合然後只發射這些Observables最近發射的數據
- Scan 連續地對數據序列的每一項應用一個函數然後連續發射結果
- Buffer 它定期從Observable收集數據到一個集合然後把這些數據集合打包發射而不是一次發射一個
- Window 定期將來自原始Observable的數據分解爲一個Observable窗口發射這些窗口而不是每次發射一項數據
- GroupBy 將Observable分拆爲Observable集合將原始Observable發射的數據按Key分組每一個Observable發射一組不同的數據
1. Map
—> 對序列的每一項都應用一個函數來變換Observable發射的數據序列
示例代碼:
Observable.just(1,2,3,4,5,6).map(new Func1<Integer, Integer>() {
@Override
public Integer call(Integer integer) {
//對源Observable產生的結果,都統一乘以3處理
return integer*3;
}
}).subscribe(new Action1<Integer>() {
@Override
public void call(Integer integer) {
System.out.println("next:" + integer);
}
});
輸出
next:3
next:6
next:9
next:12
next:15
next:18
- Javadoc:map(Func1)
2. Cast
—> 操作符將原始Observable發射的每一項數據都強制轉換爲一個指定的類型,然後再發射數據,它是map的一個特殊版本。
cast
操作符類似於map
操作符,不同的地方在於map
操作符可以通過自定義規則,把一個值A1
變成另一個值A2
,A1
和A2
的類型可以一樣也可以不一樣;而cast
操作符主要是做類型轉換的,傳入參數爲類型class
,如果源Observable
產生的結果不能轉成指定的class
,則會拋出ClassCastException
運行時異常。
示例代碼:
Observable.just(1,2,3,4,5,6).cast(Integer.class).subscribe(new Action1<Integer>() {
@Override
public void call(Integer value) {
System.out.println("next:"+value);
}
});
輸出
next:1
next:2
next:3
next:4
next:5
next:6
- Javadoc:cast(Class)
3. FlatMap
—> 將Observable發射的數據集合變換爲Observables集合,然後將這些Observable發射的數據平坦化的放進一個單獨的Observable
FlatMap
將一個發射數據的Observable變換爲多個Observables
,然後將它們發射的數據合併後放進一個單獨的Observable
FlatMap
操作符使用一個指定的函數對原始Observable
發射的每一項數據執行變換操作,這個函數返回一個本身也發射數據的Observable
,然後FlatMap
合併這些Observables
發射的數據,最後將合併後的結果當做它自己的數據序列發射。
這個方法是很有用的,例如,當你有一個這樣的Observable
:它發射一個數據序列,這些數據本身包含Observable
成員或者可以變換爲Observable
,因此你可以創建一個新的Observable
發射這些次級Observable
發射的數據的完整集合。
Student[] students = ...;
Subscriber<Course> subscriber = new Subscriber<Course>() {
@Override
public void onNext(Course course) {
Log.d(tag, course.getName());
}
...
};
Observable.from(students)
.flatMap(new Func1<Student, Observable<Course>>() {
@Override
public Observable<Course> call(Student student) {
return Observable.from(student.getCourses());
}
})
.subscribe(subscriber);
注意:FlatMap
對這些Observables
發射的數據做的是合併(merge
)操作,因此它們可能是交錯的。
在許多語言特定的實現中,還有一個操作符不會讓變換後的Observables
發射的數據交錯,它按照嚴格的順序發射這些數據,這個操作符通常被叫作ConcatMap
或者類似的名字。
注意:如果任何一個通過這個flatMap
操作產生的單獨的Observable
調用onError
異常終止了,這個Observable
自身會立即調用onError
並終止。
這個操作符有一個接受額外的int
參數的一個變體。這個參數設置flatMap
從原來的Observable
映射Observables
的最大同時訂閱數。當達到這個限制時,它會等待其中一個終止然後再訂閱另一個。
- Javadoc: flatMap(Func1)
- Javadoc:flatMap(Func1,int)
4. ConcatMap
—> 它類似於最簡單版本的flatMap,但是它按次序連接而不是合併那些生成的Observables,然後產生自己的數據序列。
concatMap()
函數解決了flatMap()
的交叉問題,提供了一種能夠把發射的值連續在一起的鋪平函數,而不是合併它們
看這篇文章flatMap()
vs concatMap
,點我點我
- Javadoc:concatMap(Func1)
5. SwitchMap
—> 將Observable發射的數據集合變換爲Observables集合,然後只發射這些Observables最近發射的數據
它和flatMap很像,除了一點:當原始Observable發射一個新的數據(Observable)時,它將取消訂閱並停止監視產生執之前那個數據的Observable,只監視當前這一個。
示例代碼:
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() {
System.out.println("------>onCompleted()");
}
@Override
public void onError(Throwable e) {
System.out.println("------>onError()" + e);
}
@Override
public void onNext(String s) {
System.out.println("------>onNext:" + s);
}
});
}
輸出
------>onNext:E
------>onCompleted()
- Javadoc: switchMap(Func1)
6. Scan
—> 連續地對數據序列的每一項應用一個函數,然後連續發射結果
Scan
操作符對原始Observable
發射的第一項數據應用一個函數,然後將那個函數的結果作爲自己的第一項數據發射。它將函數的結果同第二項數據一起填充給這個函數來產生它自己的第二項數據。它持續進行這個過程來產生剩餘的數據序列。這個操作符在某些情況下被叫做accumulator
。
示例代碼:
Observable.just(1, 2, 3, 4, 5)
.scan(new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer sum, Integer item) {
return sum + item;
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onNext(Integer item) {
System.out.println("Next: " + item);
}
@Override
public void onError(Throwable error) {
System.err.println("Error: " + error.getMessage());
}
@Override
public void onCompleted() {
System.out.println("Sequence complete.");
}
});
輸出:
Next: 1
Next: 3
Next: 6
Next: 10
Next: 15
Sequence complete.
有一個scan
操作符的變體,你可以傳遞一個種子值給累加器函數的第一次調用(Observable
發射的第一項數據)。如果你使用這個版本,scan
將發射種子值作爲自己的第一項數據。注意:傳遞null
作爲種子值與不傳遞是不同的,null
種子值是合法的。
示例代碼
Observable.just(1,2,3,4,5).scan(100, new Func2<Integer, Integer, Integer>() {
@Override
public Integer call(Integer integer, Integer integer2) {
return integer + integer2;
}
}).subscribe(new Subscriber<Integer>() {
@Override
public void onCompleted() {
System.out.println("Sequence complete.");
}
@Override
public void onError(Throwable e) {
System.err.println("Error: " + e.getMessage());
}
@Override
public void onNext(Integer integer) {
System.out.println("Next: " + integer);
}
});
輸出
Next: 100
Next: 101
Next: 103
Next: 106
Next: 110
Next: 115
- Javadoc:scan(Func2)
- Javadoc:scan(R,Func2)
7. Buffer
—> 它定期從Observable收集數據到一個集合,然後把這些數據集合打包發射,而不是一次發射一個
Buffer
操作符將一個Observable
變換爲另一個,原來的Observable
正常發射數據,變換產生的Observable
發射這些數據的緩存集合。Buffer
操作符在很多語言特定的實現中有很多種變體,它們在如何緩存這個問題上存在區別。
注意:如果原來的Observable
發射了一個onError
通知,Buffer會立即傳遞這個通知,而不是首先發射緩存的數據,即使在這之前緩存中包含了原始Observable
發射的數據。
Window
操作符與Buffer
類似,但是它在發射之前把收集到的數據放進單獨的Observable
,而不是放進一個數據結構。
在RxJava
中有許多Buffer
的變體:
buffer(count)
buffer(count)
以列表(List
)的形式發射非重疊的緩存,每一個緩存至多包含來自原始Observable
的count
項數據(最後發射的列表數據可能少於count
項)
示例代碼
Observable.range(1,5).buffer(2).subscribe(new Observer<List<Integer>>() {
@Override
public void onCompleted() {
System.out.println("-----------------onCompleted:");
}
@Override
public void onError(Throwable e) {
System.out.println("----------------->onError:");
}
@Override
public void onNext(List<Integer> strings) {
System.out.println("----------------->onNext:" + strings);
}
});
輸出
----------------->onNext:[1, 2]
----------------->onNext:[3, 4]
----------------->onNext:[5]
-----------------onCompleted:
- Javadoc:buffer(int)
buffer(count, skip)
buffer(count, skip)
從原始Observable的第一項數據開始創建新的緩存,此後每當收到skip
項數據,用count
項數據填充緩存:開頭的一項和後續的count-1
項,它以列表(List)
的形式發射緩存,取決於count
和skip
的值,這些緩存可能會有重疊部分(比如skip < count
時),也可能會有間隙(比如skip > count
時)。
示例代碼: 取4
個數 每次跳過2
個
Observable.range(1, 5).buffer(4, 2).subscribe(new Observer<List<Integer>>() {
@Override
public void onCompleted() {
System.out.println("-----------------onCompleted:");
}
@Override
public void onError(Throwable e) {
System.out.println("----------------->onError:");
}
@Override
public void onNext(List<Integer> strings) {
System.out.println("----------------->onNext:" + strings);
}
});
輸出:
----------------->onNext:[1, 2, 3, 4]
----------------->onNext:[3, 4, 5]
----------------->onNext:[5]
-----------------onCompleted:
- Javadoc:buffer(int,int)
buffer(timespan, unit[, scheduler])
buffer(timespan, unit)
定期以List的形式發射新的數據,每個時間段,收集來自原始Observable
的數據(從前面一個數據包裹之後,或者如果是第一個數據包裹,從有觀察者訂閱原來的Observale
之後開始)。還有另一個版本的buffer
接受一個Scheduler
參數,默認情況下會使用computation
調度器。
示例代碼:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");//設置日期格式
Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
if (subscriber.isUnsubscribed())
return;
try{
while (true){
subscriber.onNext("數據:"+df.format(new Date()));
SystemClock.sleep(2000);
}
}catch (Exception e){
subscriber.onError(e);
}
}
}).buffer(3,TimeUnit.SECONDS).subscribe(new Action1<List<String>>() {
@Override
public void call(List<String> strings) {
String s ="";
for (int i = 0 ; i < strings.size(); i++){
s = s+ ","+ strings.get(i);
}
System.out.println(s);
}
});
輸出
,數據:2016-07-07 10:30:27,數據:2016-07-07 10:30:29
,數據:2016-07-07 10:30:31
,數據:2016-07-07 10:30:33,數據:2016-07-07 10:30:35
,數據:2016-07-07 10:30:37
,數據:2016-07-07 10:30:39,數據:2016-07-07 10:30:41
,數據:2016-07-07 10:30:43
- Javadoc:buffer(long,TimeUnit)
- Javadoc:buffer(long,TimeUnit,Scheduler)
8. Window
—> 定期將來自原始Observable的數據分解爲一個Observable窗口,發射這些窗口,而不是每次發射一項數據
Window
和Buffer
類似,但不是發射來自原始Observable
的數據包,它發射的是Observables
,這些Observables
中的每一個都發射原始Observable
數據的一個子集,最後發射一個onCompleted
通知。
示例代碼:
Observable.interval(1,TimeUnit.SECONDS).take(10).window(3,TimeUnit.SECONDS).subscribe(new Observer<Observable<Long>>() {
@Override
public void onCompleted() {
LogUtils.d("------>onCompleted()");
}
@Override
public void onError(Throwable e) {
LogUtils.d("------>onError()" + e);
}
@Override
public void onNext(Observable<Long> integerObservable) {
LogUtils.d("------->onNext()");
integerObservable.subscribe(new Action1<Long>() {
@Override
public void call(Long integer) {
LogUtils.d("------>call():" + integer);
}
});
}
});
輸出:
I/System.out: ------>call():0
I/System.out: ------>call():1
I/System.out: ------->onNext()
I/System.out: ------>call():2
I/System.out: ------>call():3
I/System.out: ------>call():4
I/System.out: ------->onNext()
I/System.out: ------>call():5
I/System.out: ------>call():6
I/System.out: ------>call():7
I/System.out: ------->onNext()
I/System.out: ------>call():8
I/System.out: ------>call():9
I/System.out: ------>onCompleted()
- Javadoc: window(long,TimeUnit)
Javadoc: window(long,TimeUnit,Scheduler)
9. GroupBy
—> 將Observable分拆爲Observable集合,將原始Observable發射的數據按Key分組,每一個Observable發射一組不同的數據
GroupBy
操作符將原始Observable
分拆爲一些Observables
集合,它們中的每一個發射原始Observable
數據序列的一個子序列。哪個數據項由哪一個Observable
發射是由一個函數判定的,這個函數給每一項指定一個Key
,Key
相同的數據會被同一個Observable
發射。
RxJava
實現了groupBy
操作符。它返回Observable
的一個特殊子類GroupedObservable
,實現了GroupedObservable
接口的對象有一個額外的方法getKey
,這個Key
用於將數據分組到指定的Observable
。
有一個版本的groupBy
允許你傳遞一個變換函數,這樣它可以在發射結果GroupedObservable
之前改變數據項。
注意:groupBy
將原始Observable
分解爲一個發射多個GroupedObservable
的Observable
,一旦有訂閱,每個GroupedObservable
就開始緩存數據。因此,如果你忽略這些GroupedObservable
中的任何一個,這個緩存可能形成一個潛在的內存泄露。因此,如果你不想觀察,也不要忽略GroupedObservable
。你應該使用像take(0)
這樣會丟棄自己的緩存的操作符。
如果你取消訂閱一個GroupedObservable
,那個Observable
將會終止。如果之後原始的Observable
又發射了一個與這個Observable
的Key
匹配的數據,groupBy
將會爲這個Key
創建一個新的GroupedObservable
。
groupBy
默認不在任何特定的調度器上執行。
示例代碼:
Observable.interval(1, TimeUnit.SECONDS).take(10).groupBy(new Func1<Long, Long>() {
@Override
public Long call(Long value) {
//按照key爲0,1,2分爲3組
return value % 3;
}
}).subscribe(new Action1<GroupedObservable<Long, Long>>() {
@Override
public void call(GroupedObservable<Long, Long> result) {
result.subscribe(new Action1<Long>() {
@Override
public void call(Long value) {
System.out.println("key:" + result.getKey() +", value:" + value);
}
});
}
});
輸出:
key:0, value:0
key:1, value:1
key:2, value:2
key:0, value:3
key:1, value:4
key:2, value:5
key:0, value:6
key:1, value:7
key:2, value:8
key:0, value:9
- Javadoc :groupBy(Func1)
- Javadoc :groupBy(Func1,Func1)