首頁 > 軟體

SpringCloudRPC核心原理:RxJava響應式程式設計框架,轉換型操作符

2021-05-30 11:30:42

轉換型操作符

本節介紹RxJava的3個轉換型操作符:map操作符、flatMap操作符和scan操作符。

map操作符

map操作符接受一個轉換函數,對Observable彈射的訊息流中的每一個元素應用該轉換函數,轉換之後的結果從訊息流彈出。map操作符返回的訊息流由轉換函數執行轉換之後的結果組成。

map操作符的處理流程如圖4-6所示。

圖4-6 map操作符的處理流程

map操作符需要接收一個函數式介面Function<T,R>的物件,該物件實現了介面的apply(T)方法,此方法負責對接收到的實參進行轉換,返回轉換之後的新值。

map操作符的使用例項如下:

package com.crazymaker.demo.rxJava.basic;//省略import@Slf4jpublic class TransformationDemo{ /***演示map轉換*/ @Test public void mapDemo() { Observable.range(1, 4) .map(i -> i *i) .subscribe(i -> log.info(i.toString())); }...}

運行這個演示程式,輸出的結果如下:

[main] INFO c.c.d.r.b.TransformationDemo - 1[main] INFO c.c.d.r.b.TransformationDemo - 4[main] INFO c.c.d.r.b.TransformationDemo - 9[main] INFO c.c.d.r.b.TransformationDemo - 16

map操作符從訊息流中取一個值,然後返回另一個值,轉換的邏輯是一對一的,而flatMap操作符的邏輯並不是如此。

flatMap操作符

flatMap操作符將輸入訊息流的任意數量的元素(零項或無窮項)打包成一個新的Observable主題然後彈出。

flatMap操作符的處理流程如圖4-7所示。

圖4-7 flatMap操作符的處理流程

flatMap操作符將一個彈射資料的Observable流變換為一個彈射Observable主題物件的新流,新流所彈出的主題物件(元素)會包含源流中的一個或者多個數據元素,其特點如下:

(1)flatMap轉換是一對一類型或者一對多類型的,原來彈射了幾個資料,轉換之後可以是更多個數據。

(2)flatMap轉換同樣可以改變彈射的資料類型。

(3)flatMap轉換後的資料還是會逐個發射給下游的Subscriber來接收,表面上就像這些資料是由一個Observable發射的一樣,其實是多個Observable發射然後合併的。一個簡單的flatMap操作符的使用例項如下:

package com.crazymaker.demo.rxJava.basic;//省略import@Slf4jpublic class TransformationDemo{ ... /** *演示flapMap轉換 */ @Test public void flapMapDemo() { /** *注意 flatMap 中的just創建的是一個新流 */ Observable.range(1, 4) .flatMap(i -> Observable.just(i *i, i *i + 1)) .subscribe(i -> log.info(i.toString())); }}

運行這個演示程式,輸出的結果如下:

[main] INFO c.c.d.r.b.TransformationDemo - 1[main] INFO c.c.d.r.b.TransformationDemo - 2[main] INFO c.c.d.r.b.TransformationDemo - 4[main] INFO c.c.d.r.b.TransformationDemo - 5[main] INFO c.c.d.r.b.TransformationDemo - 9[main] INFO c.c.d.r.b.TransformationDemo - 10[main] INFO c.c.d.r.b.TransformationDemo - 16[main] INFO c.c.d.r.b.TransformationDemo - 17

由於在轉換的過程中flatMap操作符創建了新的Observable主題物件,因此其可以被歸類為創建型操作符。一個更復雜的flatMap操作符的使用例項如下:

package com.crazymaker.demo.rxJava.basic;//省略import@Slf4jpublic class TransformationDemo{ ... /** *演示一個稍微複雜的flapMap轉換 */ @Test public void flapMapDemo2() { Observable.range(1, 4) .flatMap(i -> Observable.range(1, i).toList()) .subscribe(list -> log.info(list.toString())); }}

在這個使用例項中,flatMap把輸入流的元素通過range創建型操作符轉成一個Observable物件,然後呼叫其toList()方法轉換成包裝單個List元素的新Observable主題物件並彈出。運行這個演示程式,輸出的結果如下:

[main] INFO c.c.d.r.b.TransformationDemo - [1][main] INFO c.c.d.r.b.TransformationDemo - [1, 2][main] INFO c.c.d.r.b.TransformationDemo - [1, 2, 3][main] INFO c.c.d.r.b.TransformationDemo - [1, 2, 3, 4]

scan操作符

scan操作符對一個Observable流序列的每一項資料應用一個累積函數,然後將這個函數的累積結果彈射出去。除了第一項之外,scan操作符會將上一個資料項的累積結果作為下一個資料項在應用累積函數時的輸入,所以scan操作符有點類似遞迴操作。

假定累積函數為一個簡單的累加函數,然後使用scan操作符對1~5的資料流序列進行掃描,它的執行流程如圖4-8所示。

圖4-8 使用scan操作符對1~5的資料流序列進行累加掃描

使用scan操作符對1~5的資料流序列進行掃描,並使用累加函數進行累加,參考如下的實現程式碼:

package com.crazymaker.demo.rxJava.basic;//省略import@Slf4jpublic class TransformationDemo{ /**演示scan操作符掃描*/ @Test public void scanDemo() { /**定義一個accumulator累積函數 */ Func2<Integer, Integer, Integer> accumulator = new Func2<Integer, Integer, Integer>() { @Override public Integer call(Integer input1, Integer input2) { log.info(" {} + {} = {} ", input1, input2, input1 + input2); return input1 + input2; } }; /** *使用scan進行流掃描 */ Observable.range(1, 5) .scan(accumulator) .subscribe(new Action1<Integer>() { @Override public void call(Integer sum) { log.info(" 累加的結果: {} ", sum); } }); }}

運行以上程式碼,輸出的結果節選如下:

[main] INFO c.c.d.r.b.TransformationDemo - 累加的結果: 1[main] INFO c.c.d.r.b.TransformationDemo - 1 + 2 = 3[main] INFO c.c.d.r.b.TransformationDemo - 累加的結果: 3[main] INFO c.c.d.r.b.TransformationDemo - 3 + 3 = 6[main] INFO c.c.d.r.b.TransformationDemo - 累加的結果: 6[main] INFO c.c.d.r.b.TransformationDemo - 6 + 4 = 10[main] INFO c.c.d.r.b.TransformationDemo - 累加的結果: 10[main] INFO c.c.d.r.b.TransformationDemo - 10 + 5 = 15[main] INFO c.c.d.r.b.TransformationDemo - 累加的結果: 15

以上例項中,scan操作符對原Observable流所彈射的第一項資料1應用了accumulator累積函數,然後將累積函數的結果1作為輸出流的第一項資料彈射出去;接下來,它將第一個結果連同原始Observable流的第二項資料2一起,再填充給accumulator累積函數,之後將累積結果3作為輸出流的第二項資料彈射出去。scan操作符持續重複這個過程,不斷對原流進行累積,直到其最後一個數據項的累積結果從輸出流彈射出去。

本文給大家講解的內容是SpringCloudRPC遠端呼叫核心原理: RxJava響應式程式設計框架,轉換型操作符

下篇文章給大家講解的是SpringCloudRPC遠端呼叫核心原理: RxJava響應式程式設計框架,聚合操作符;覺得文章不錯的朋友可以轉發此文關注小編;感謝大家的支援!


IT145.com E-mail:sddin#qq.com