RxJava2--操作符Operator

介紹

在RxJava的事件流轉(zhuǎn)過(guò)程中窖式,可以改變事件中的事件以及數(shù)據(jù)怀吻,使用的就是RxJava提供的操作符。

RxJava2-Android-Samples的ReadMe.md中可以看到有如下操作符

操作符 操作符 操作符 操作符
Map Zip Reduce Filter
FlatMap Take Skip Buffer
Concat Replay Merge

而在Operators的文檔中圖文并茂展示出各個(gè)操作符的作用接下來(lái)會(huì)介紹這些操作符的作用與使用方法

Map

Map的作用:
將發(fā)射的事件進(jìn)行Map函數(shù)定義的數(shù)據(jù)轉(zhuǎn)換,再將轉(zhuǎn)換后的事件發(fā)射給Observer洼裤。

Map

如下示例:

  1. 通過(guò)Emitter發(fā)射12肛鹏,3三個(gè)事件
  2. 中間會(huì)通過(guò)Map進(jìn)行轉(zhuǎn)換逸邦,轉(zhuǎn)換后的事件為10恩沛,2030
  3. 再將轉(zhuǎn)換后的事件發(fā)送給Observer
Observable.create<Int> { emitter ->
            emitter.onNext(1)
            emitter.onNext(2)
            emitter.onNext(3)
        }.map { value ->
            value * 10
        }.subscribe { data ->
            Log.e(TAG, "Consumer onNext...$data")
        }

Zip

Zip操作符的作用:
將多個(gè)發(fā)射器的事件按順序合并成單個(gè)事件流發(fā)射缕减,如果多個(gè)發(fā)射器之間的事件數(shù)不相等雷客,則合并后的事件數(shù)以少的為準(zhǔn)。


Zip

如下示例:

  1. 通過(guò)Observable.interval創(chuàng)建0桥狡,1搅裙,2這三個(gè)事件的發(fā)射器
  2. 通過(guò)Observable.interval創(chuàng)建ab裹芝,c部逮,de對(duì)應(yīng)ASCII碼的發(fā)射器嫂易,并且通過(guò)filter過(guò)濾其他的ASCII碼值兄朋,因?yàn)?code>a的ASCII是97,通過(guò)take獲取前面6個(gè)元素
  3. 調(diào)用Observable.zip創(chuàng)建一個(gè)合并了numschars的發(fā)射器怜械,并且通過(guò)BiFunction將兩個(gè)發(fā)射器發(fā)射的數(shù)據(jù)進(jìn)行合并
  4. 通過(guò)合并后的發(fā)射器颅和,調(diào)用subscribe來(lái)接收事件
// Genertate values 0,1,2
val nums = Observable.interval(250, TimeUnit.MILLISECONDS).take(3)
//Generate values a,b,c,d,e,f.....a的ASCII是97
val chars = Observable.interval(150, TimeUnit.MILLISECONDS).filter { i -> i >= 97 }.take(6)
val newObservable = Observable.zip(nums, chars, BiFunction<Long, Long, String> { x, y -> "$x....${y.toChar()}" })
newObservable.subscribe { value ->
    Log.e(TAG, "Subscribe...$value")
}

打印出來(lái)的日志如下:

Subscribe...0....a
Subscribe...1....b
Subscribe...2....c

注釋:

  1. Observable.interval是根據(jù)傳入的參數(shù)生成順序數(shù)組的方法。如上例所示缕允,每隔250毫秒就會(huì)發(fā)送一個(gè)從0開(kāi)始的事件峡扩,發(fā)送0,1障本,2教届,3...一直累加的事件
  2. zip只會(huì)以最少的發(fā)射器數(shù)量為標(biāo)準(zhǔn)合并事件。如上例所示驾霜,nums發(fā)射器發(fā)送0,1,2這3個(gè)事件案训,而chars發(fā)送ab寄悯,c萤衰,de猜旬,f這5個(gè)事件脆栋,但是合并過(guò)后,只會(huì)產(chǎn)生3個(gè)事件

Reduce

Reduce本意是減少的意思洒擦,而它的作用也就是將發(fā)射器的事件都合并到一個(gè)事件中椿争,以減少事件的接收。

Reduce

如下示例:

  1. 每250毫秒發(fā)送一個(gè)事件
  2. reduce接收的函數(shù)中熟嫩,每次將發(fā)送的事件結(jié)果與之前的事件結(jié)果相加秦踪,并且返回
  3. subscribe中訂閱最終的事件
Observable.interval(250, TimeUnit.MILLISECONDS).take(6).reduce { t1: Long?, t2: Long? ->
            Log.e(TAG, "t1:$t1....t2:$t2")
            t1?.plus(t2 ?: 0)
        }.subscribe { value ->
            Log.e(TAG, "subscribe $value")
        }

打印日志如下:

t1:0....t2:1
t1:1....t2:2
t1:3....t2:3
t1:6....t2:4
t1:10....t2:5
subscribe 15

Filter

Filter名為過(guò)濾,與其名相似,Filter的作用就是按條件過(guò)濾事件椅邓,只有返回true的事件才能繼續(xù)往Observer傳遞

Filter

如上圖所示柠逞,如果發(fā)送的數(shù)大于10,則允許發(fā)射景馁,否則會(huì)被過(guò)濾

FlatMap

FlatMap名為扁平映射板壮,它的作用就是將發(fā)射端的事件按照FlatMap中定義的策略進(jìn)行拆分,拆分成多個(gè)事件后合住,繼續(xù)向下傳遞事件

FlatMap

如下示例:
在最開(kāi)始的發(fā)射端绰精,發(fā)射01透葛,2笨使,而經(jīng)過(guò)了flatMap之后,會(huì)將每個(gè)接收的事件進(jìn)行處理僚害,處理后進(jìn)行二次發(fā)射硫椰。也就是將0這個(gè)事件轉(zhuǎn)換成了Receive:0以及Emitter:100這兩個(gè)事件往下發(fā)送,所以贡珊,在Observer端接收到的事件就是這兩個(gè)事件了最爬。

Observable.fromArray(0, 1, 2).flatMap { value ->
            Observable.create<String> { emitter ->
                emitter.onNext("Receive:$value")
                emitter.onNext("Emitter:${value + 100}")
                emitter.onComplete()
            }
        }.subscribe {
            Log.e(TAG, "Subscribe:$")
        }

打印的日志如下:

  E/SelectImageActivity: Subscribe:Receive:0
  E/SelectImageActivity: Subscribe:Emitter:100
  E/SelectImageActivity: Subscribe:Receive:1
  E/SelectImageActivity: Subscribe:Emitter:101
  E/SelectImageActivity: Subscribe:Receive:2
  E/SelectImageActivity: Subscribe:Emitter:102

Take與TakeLast

Take的作用比較簡(jiǎn)單,指的就是獲取前面N個(gè)事件门岔,后面的事件則會(huì)直接拋棄


Take

而TakeLast的作用則是獲取后面的N個(gè)事件,而前面的事件會(huì)直接拋棄


TakeLast

Skip與SkipLast

Skip的作用就是跳過(guò)N個(gè)事件


Skip

SkipLast的作用則就是跳過(guò)后面的N個(gè)事件烤送,例如發(fā)送了4個(gè)事件寒随,12帮坚,3妻往,4,而SkipLast(2)试和,則會(huì)跳過(guò)后面的3讯泣,4,只發(fā)送1阅悍,2好渠。而如果只發(fā)送2個(gè)事件的話,則SkipLast(2)調(diào)用后节视,則不會(huì)發(fā)送任何事件拳锚。

SkipLast

Buffer

Buffer即為緩沖,會(huì)將發(fā)射的事件積攢到count數(shù)量后寻行,統(tǒng)一發(fā)送給Observer霍掺,而Obserer端接收到到則是一個(gè)MutableList。如果發(fā)射到最后,即使沒(méi)有滿足條件杆烁,也會(huì)將剩下到打包發(fā)送

Buffer

如下示例:

Observable.fromArray(0, 1, 2, 3, 4).buffer(3).subscribe { list ->
            Log.e(TAG, "Receive List:$list")
            list.forEach { item ->
                Log.e(TAG, "Receive Item:$item")
            }
        }

輸出如下:

  E/SelectImageActivity: Receive List:[0, 1, 2]
  E/SelectImageActivity: Receive Item:0
  E/SelectImageActivity: Receive Item:1
  E/SelectImageActivity: Receive Item:2
  E/SelectImageActivity: Receive List:[3, 4]
  E/SelectImageActivity: Receive Item:3
  E/SelectImageActivity: Receive Item:4

Concat

Concat可以做到多個(gè)發(fā)射器并行發(fā)射事件牙丽,而在接收端會(huì)在接收完前一個(gè)發(fā)射器的事件后,再接收下一個(gè)發(fā)射器的事件兔魂,接收順序不會(huì)交錯(cuò)烤芦。


Concat

如下例子:

val emitter1 = Observable.fromArray(0, 1, 2)
val emitter2 = Observable.fromArray('a', 'b', 'c')
Observable.concat(emitter1, emitter2).subscribe {
       Log.e(TAG, "Subscribe...$it")
}

輸出的日志如下:

E/SelectImageActivity: Subscribe...0
E/SelectImageActivity: Subscribe...1
E/SelectImageActivity: Subscribe...2
E/SelectImageActivity: Subscribe...a
E/SelectImageActivity: Subscribe...b
E/SelectImageActivity: Subscribe...c

Replay

Replay的作用也就是在事件已經(jīng)被前一個(gè)Observer接收后,當(dāng)下一個(gè)Observer重新Subscribe時(shí)入热,仍然可以將之前的事件傳遞給新的Obserer拍棕,有點(diǎn)類似于Sticky

image.png

如下示例:
創(chuàng)建一個(gè)ReplaySubject,然后在第一個(gè)Observer中打印First Subscribe勺良,發(fā)射完1绰播,23尚困,4之后蠢箩,再重新讓一個(gè)新的Observer訂閱該發(fā)射器,在第二個(gè)Observer中打印Second Subscribe事甜。

val replaySubject = ReplaySubject.create<Int>()
replaySubject.subscribe {
    Log.e(TAG, "First Subscribe:$it")
}
replaySubject.onNext(1)
replaySubject.onNext(2)
replaySubject.onNext(3)
replaySubject.onNext(4)
replaySubject.subscribe {
    Log.e(TAG, "Second Subscribe:$it")
}

輸出結(jié)果如下:

First Subscribe:1
First Subscribe:2
First Subscribe:3
First Subscribe:4
Second Subscribe:1
Second Subscribe:2
Second Subscribe:3
Second Subscribe:4

Merge

Merge的作用可以讓多個(gè)發(fā)射器同時(shí)發(fā)射谬泌,并且在Observer端接收時(shí),按發(fā)射事件的時(shí)間順序來(lái)接收


Merge

如下示例:

val emitter1 = Observable.fromArray(0, 1, 2)
val emitter2 = Observable.fromArray('a', 'b', 'c')
Observable.merge(emitter1, emitter2).subscribe {
     Log.e(TAG, "Subscribe...$it")
}

輸出的結(jié)果:

E/SelectImageActivity: Subscribe...0
E/SelectImageActivity: Subscribe...1
E/SelectImageActivity: Subscribe...2
E/SelectImageActivity: Subscribe...a
E/SelectImageActivity: Subscribe...b
E/SelectImageActivity: Subscribe...c
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末逻谦,一起剝皮案震驚了整個(gè)濱河市掌实,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌邦马,老刑警劉巖贱鼻,帶你破解...
    沈念sama閱讀 222,252評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異滋将,居然都是意外死亡邻悬,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,886評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門随闽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)父丰,“玉大人,你說(shuō)我怎么就攤上這事掘宪《晟龋” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,814評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵添诉,是天一觀的道長(zhǎng)屁桑。 經(jīng)常有香客問(wèn)我,道長(zhǎng)栏赴,這世上最難降的妖魔是什么蘑斧? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,869評(píng)論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上竖瘾,老公的妹妹穿的比我還像新娘沟突。我一直安慰自己,他們只是感情好捕传,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,888評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布惠拭。 她就那樣靜靜地躺著,像睡著了一般庸论。 火紅的嫁衣襯著肌膚如雪职辅。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 52,475評(píng)論 1 312
  • 那天聂示,我揣著相機(jī)與錄音域携,去河邊找鬼。 笑死鱼喉,一個(gè)胖子當(dāng)著我的面吹牛秀鞭,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播扛禽,決...
    沈念sama閱讀 41,010評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼锋边,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了编曼?” 一聲冷哼從身側(cè)響起豆巨,我...
    開(kāi)封第一講書(shū)人閱讀 39,924評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎掐场,沒(méi)想到半個(gè)月后搀矫,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,469評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刻肄,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,552評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了融欧。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片敏弃。...
    茶點(diǎn)故事閱讀 40,680評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖噪馏,靈堂內(nèi)的尸體忽然破棺而出麦到,到底是詐尸還是另有隱情,我是刑警寧澤欠肾,帶...
    沈念sama閱讀 36,362評(píng)論 5 351
  • 正文 年R本政府宣布瓶颠,位于F島的核電站,受9級(jí)特大地震影響刺桃,放射性物質(zhì)發(fā)生泄漏粹淋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,037評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望桃移。 院中可真熱鬧屋匕,春花似錦、人聲如沸借杰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,519評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)蔗衡。三九已至纤虽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間绞惦,已是汗流浹背逼纸。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,621評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留翩隧,地道東北人樊展。 一個(gè)月前我還...
    沈念sama閱讀 49,099評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像堆生,于是被迫代替她去往敵國(guó)和親专缠。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,691評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容

  • 一淑仆、RxJava操作符概述 RxJava中的操作符就是為了提供函數(shù)式的特性涝婉,函數(shù)式最大的好處就是使得數(shù)據(jù)處理簡(jiǎn)潔易...
    無(wú)求_95dd閱讀 3,112評(píng)論 0 21
  • 轉(zhuǎn)載自:https://xiaobailong24.me/2017/03/18/Android-RxJava2.x...
    Young1657閱讀 2,026評(píng)論 1 9
  • 一、RxJava操作符概述 RxJava中的操作符就是為了提供函數(shù)式的特性蔗怠,函數(shù)式最大的好處就是使得數(shù)據(jù)處理簡(jiǎn)潔易...
    BrotherChen閱讀 1,625評(píng)論 0 10
  • 一墩弯、RxJava操作符概述 RxJava中的操作符就是為了提供函數(shù)式的特性,函數(shù)式最大的好處就是使得數(shù)據(jù)處理簡(jiǎn)潔易...
    測(cè)天測(cè)地測(cè)空氣閱讀 637評(píng)論 0 1
  • 本篇文章介主要紹RxJava中操作符是以函數(shù)作為基本單位寞射,與響應(yīng)式編程作為結(jié)合使用的渔工,對(duì)什么是操作、操作符都有哪些...
    嘎啦果安卓獸閱讀 2,866評(píng)論 0 10