摘要:從這一章開始,我們開始聊聊中的操作符,后面我將用三章的篇幅來分別介紹轉換類操作符過濾類操作符組合類操作符這一章我們主要講講轉換類操作符。函數(shù)同樣也是做轉換的,但是作用卻不一樣。
轉載請注明出處:https://zhuanlan.zhihu.com/p/21926591
RxJava系列1(簡介)
RxJava系列2(基本概念及使用介紹)
RxJava系列3(轉換操作符)
RxJava系列4(過濾操作符)
RxJava系列5(組合操作符)
RxJava系列6(從微觀角度解讀RxJava源碼)
RxJava系列7(最佳實踐)
前面兩篇文章中我們介紹了RxJava的一些基本概念和RxJava最簡單的用法。從這一章開始,我們開始聊聊RxJava中的操作符Operators,后面我將用三章的篇幅來分別介紹:
轉換類操作符
過濾類操作符
組合類操作符
這一章我們主要講講轉換類操作符。所有這些Operators都作用于一個可觀測序列,然后變換它發(fā)射的值,最后用一種新的形式返回它們。概念實在是不好理解,下面我們結合實際的例子一一介紹。
Mapmap(Func1)函數(shù)接受一個Func1類型的參數(shù)(就像這樣map(Func1 super T, ? extends R> func)),然后吧這個Func1應用到每一個由Observable發(fā)射的值上,將發(fā)射的只轉換為我們期望的值。這種狗屁定義我相信你也聽不懂,我們來看一下官方給出的原理圖:
假設我們需要將一組數(shù)字裝換成字符串,我們可以通過map這樣實現(xiàn):
Observable.just(1, 2, 3, 4, 5) .map(new Func1() { @Override public String call(Integer i) { return "This is " + i; } }).subscribe(new Action1 () { @Override public void call(String s) { System.out.println(s); } });
FlatMapFunc1構造函數(shù)中的兩個參數(shù)分別是Observable發(fā)射值當前的類型和map轉換后的類型,上面這個例子中發(fā)射值當前的類型是Integer,轉換后的類型是String。
flatMap(Func1)函數(shù)同樣也是做轉換的,但是作用卻不一樣。flatMap不太好理解,我們直接看例子(我們公司是個房產(chǎn)平臺,那我就拿房子舉例):假設我們有一組小區(qū)數(shù)據(jù)Community[] communites,現(xiàn)在我們要輸出每個小區(qū)的名字;我們可以這樣實現(xiàn):
Observable.from(communities) .map(new Func1() { @Override public String call(Community community) { return community.name; } }) .subscribe(new Action1 () { @Override public void call(String name) { System.out.println("Community name : " + name); } });
現(xiàn)在我們需求有變化,需要打印出每個小區(qū)下面每一套房子的價格。于是我可以這樣實現(xiàn):
Community[] communities = {}; Observable.from(communities) .subscribe(new Action1() { @Override public void call(Community community) { for (House house : community.houses) { System.out.println("House price : " + house.price); } } });
如果我不想在Subscriber中使用for循環(huán),而是希望Subscriber中直接傳入單個的House對象呢?用map()顯然是不行的,因為map()是一對一的轉化,而我現(xiàn)在的要求是一對多的轉化。那么我們可以使用flatMap()把一個Community轉化成多個House。
Observable.from(communities) .flatMap(new Func1>() { @Override public Observable call(Community community) { return Observable.from(community.houses); } }) .subscribe(new Action1 () { @Override public void call(House house) { System.out.println("House price : " + house.price); } });
從前面的例子中我們發(fā)現(xiàn),flatMap()和map()都是把傳入的參數(shù)轉化之后返回另一個對象。但和map()不同的是,flatMap()中返回的是Observable對象,并且這個Observable對象并不是被直接發(fā)送到 Subscriber的回調(diào)方法中。
flatMap(Func1)的原理是這樣的:
將傳入的事件對象裝換成一個Observable對象;
這是不會直接發(fā)送這個Observable, 而是將這個Observable激活讓它自己開始發(fā)送事件;
每一個創(chuàng)建出來的Observable發(fā)送的事件,都被匯入同一個Observable,這個Observable負責將這些事件統(tǒng)一交給Subscriber的回調(diào)方法。
這三個步驟,把事件拆成了兩級,通過一組新創(chuàng)建的Observable將初始的對象『鋪平』之后通過統(tǒng)一路徑分發(fā)了下去。而這個『鋪平』就是flatMap()所謂的flat。
最后我們來看看flatMap的原理圖:
ConcatMapconcatMap(Func1)解決了flatMap()的交叉問題,它能夠把發(fā)射的值連續(xù)在一起,就像這樣:
flatMapIterableflatMapIterable(Func1)和flatMap()幾乎是一樣的,不同的是flatMapIterable()它轉化的多個Observable是使用Iterable作為源數(shù)據(jù)的。
Observable.from(communities) .flatMapIterable(new Func1SwitchMap>() { @Override public Iterable call(Community community) { return community.houses; } }) .subscribe(new Action1 () { @Override public void call(House house) { } });
switchMap(Func1)和flatMap(Func1)很像,除了一點:每當源Observable發(fā)射一個新的數(shù)據(jù)項(Observable)時,它將取消訂閱并停止監(jiān)視之前那個數(shù)據(jù)項產(chǎn)生的Observable,并開始監(jiān)視當前發(fā)射的這一個。
Scanscan(Func2)對一個序列的數(shù)據(jù)應用一個函數(shù),并將這個函數(shù)的結果發(fā)射出去作為下個數(shù)據(jù)應用合格函數(shù)時的第一個參數(shù)使用。
我們來看個簡單的例子:
Observable.just(1, 2, 3, 4, 5) .scan(new Func2() { @Override public Integer call(Integer integer, Integer integer2) { return integer + integer2; } }).subscribe(new Action1 () { @Override public void call(Integer integer) { System.out.print(integer+“ ”); } });
輸出結果為:
1 3 6 10 15GroupBy
groupBy(Func1)將原始Observable發(fā)射的數(shù)據(jù)按照key來拆分成一些小的Observable,然后這些小Observable分別發(fā)射其所包含的的數(shù)據(jù),和SQL中的groupBy類似。實際使用中,我們需要提供一個生成key的規(guī)則(也就是Func1中的call方法),所有key相同的數(shù)據(jù)會包含在同一個小的Observable中。另外我們還可以提供一個函數(shù)來對這些數(shù)據(jù)進行轉化,有點類似于集成了flatMap。
單純的文字描述和圖片解釋可能難以理解,我們來看個例子:假設我現(xiàn)在有一組房源List
Listhouses = new ArrayList<>(); houses.add(new House("中糧·海景壹號", "中糧海景壹號新出大平層!總價4500W起")); houses.add(new House("竹園新村", "滿五唯一,黃金地段")); houses.add(new House("中糧·海景壹號", "毗鄰湯臣一品")); houses.add(new House("竹園新村", "頂層戶型,兩室一廳")); houses.add(new House("中糧·海景壹號", "南北通透,豪華五房")); Observable > groupByCommunityNameObservable = Observable.from(houses) .groupBy(new Func1 () { @Override public String call(House house) { return house.communityName; } });
通過上面的代碼我們創(chuàng)建了一個新的Observable:groupByCommunityNameObservable,它將會發(fā)送一個帶有GroupedObservable的序列(也就是指發(fā)送的數(shù)據(jù)項的類型為GroupedObservable)。GroupedObservable是一個特殊的Observable,它基于一個分組的key,在這個例子中的key就是小區(qū)名。現(xiàn)在我們需要將分類后的房源依次輸出:
Observable.concat(groupByCommunityNameObservable) .subscribe(new Action1() { @Override public void call(House house) { System.out.println("小區(qū):"+house.communityName+"; 房源描述:"+house.desc); } });
執(zhí)行結果:
小區(qū):中糧·海景壹號; 房源描述:中糧海景壹號新出大平層!總價4500W起 小區(qū):中糧·海景壹號; 房源描述:毗鄰湯臣一品 小區(qū):中糧·海景壹號; 房源描述:南北通透,豪華五房 小區(qū):竹園新村; 房源描述:滿五唯一,黃金地段 小區(qū):竹園新村; 房源描述:頂層戶型,兩室一廳
轉換類的操作符就先介紹到這,后續(xù)還會繼續(xù)介紹組合、過濾類的操作符及源碼分析,敬請期待!
如果大家喜歡這一系列的文章,歡迎關注我的知乎專欄和GitHub。
知乎專欄:https://zhuanlan.zhihu.com/baron
GitHub:https://github.com/BaronZ88
文章版權歸作者所有,未經(jīng)允許請勿轉載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/66506.html
摘要:按照計劃這一期是要介紹框架結構和設計思想的,但是考慮到將在十月底發(fā)布正式版因此決定將框架結構和設計思想分析放到正式版發(fā)布后再做。后續(xù)我也會有一系列的文章來介紹和的區(qū)別。首選我們需要調(diào)用系統(tǒng)來獲取所有已安裝的,所以在的方法中調(diào)用。 轉載請注明出處:[https://zhuanlan.zhihu.com/p/... RxJava系列1(簡介) RxJava系列2(基本概念及使用介紹) R...
摘要:請欣賞語法清單后端掘金語法清單翻譯自的,從屬于筆者的入門與實踐系列。這篇一篇框架整合友好的文章三后端掘金一理論它始終是圍繞數(shù)據(jù)模型頁面進行開發(fā)的。 RxJava 常用操作符 - Android - 掘金 原文地址 http://reactivex.io/documenta... ... RxJava 和 Retrofit 結合使用完成基本的登錄和注冊功能 - Android - 掘...
閱讀 1273·2023-04-25 23:22
閱讀 1673·2023-04-25 20:04
閱讀 2648·2021-11-22 15:24
閱讀 2806·2021-11-11 16:54
閱讀 1887·2019-08-30 14:03
閱讀 1484·2019-08-29 16:35
閱讀 1706·2019-08-26 10:29
閱讀 2661·2019-08-23 18:01