本节介绍Rx<em>Java</em>的3个转换型操作符:map操作符、flatMap操作符和scan操作符。map操作符 map操作符接受一个转换函数,对Observable弹射的消息流中的每一个元素应用该转换函数,转换之后的结果从消息流弹出。map操作
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響應式程式設計框架,聚合操作符;覺得文章不錯的朋友可以轉發此文關注小編;感謝大家的支援!
相關文章
本节介绍Rx<em>Java</em>的3个转换型操作符:map操作符、flatMap操作符和scan操作符。map操作符 map操作符接受一个转换函数,对Observable弹射的消息流中的每一个元素应用该转换函数,转换之后的结果从消息流弹出。map操作
2021-05-30 11:30:42
「来源: |web安全工具库 ID:websec-tools」给你点烟的人有很多,劝你戒烟的人却没几个。。。--- 网易云热评 一、%00绕过 1、写一个get请求,可以显示提交的参数 <?<em>php</em>$a=$_GET['id'];echo $a;?> 2、查
2021-05-30 11:30:16
荣耀手表GSPro是一款智能运动户外手表,支持Android和<em>iOS</em>手机连接。假如你想更直观地看到自己的身体状况,可以用华为的运动健康APP连接到荣耀手表GSPro,这样运动数据可以同步到手机上,看起来更加方便。谈到定位,以
2021-05-30 11:00:54
在我的的iPhone 12 Pro 疯狂耗电个两天之后,<em>iOS</em> 14.6 毫无意外的来了 (手机突然变耗电的话,通常一周内会出现新版本<em>iOS</em>) 这版本宣称修正某些性能下降的问题,没意外的话就是底下联结讲的问题 因为更
2021-05-30 11:00:51
“通信行程卡APP2.0”的Android和<em>IOS</em>系统的下载二维码如下图: 2 进入软件,同意各授权信息后,输入手机号码并点击获取验证码,验证成功后点击“一键登录”,即可看到查询结果。 3 弹出“通信行程卡想要开启蓝牙
2021-05-30 11:00:47
奥维互动地图是由北京元生华网软件公司开发的,它包含Google地图与卫星图、百度地图、搜狗地图、天地图、Bing卫星图、等高线地图等,且各种地图模式之间可以自由切换,同时支持电脑PC端与手机移动端,在IOS、<em>Android
2021-05-30 11:00:37