【Koltin Flow(三)】Flow操作符之中間操作符(二)

目錄

【Koltin Flow(一)】五種創(chuàng)建flow的方式
【Koltin Flow(二)】Flow操作符之末端操作符
【Koltin Flow(三)】Flow操作符之中間操作符(一)
【Koltin Flow(三)】Flow操作符之中間操作符(二)
【Koltin Flow(三)】Flow操作符之中間操作符(三)
【Koltin Flow(四)】Flow背壓
【Koltin Flow(五)】SharedFlow及StateFlow

前言

  1. 本篇主要介紹的有組合操作符、回調(diào)操作符,也會涉及一些其他的操作符鹅髓。

組合操作符

1. zip zip主要實(shí)現(xiàn)組合的功能陷寝,將兩個(gè)flow一一組合發(fā)出,其中一個(gè)結(jié)束星掰,則zip結(jié)束多望。
代碼如下:
       val flow1  = listOf(1,2).asFlow()
            val flow2 = listOf("one","two","three").asFlow()
            flow1.zip(flow2){value1,value2->
                "zip $value1,$value2"
            }.collect {
                Log.d(TAG.TAG,it)
            }
日志如下:
2022-08-01 11:29:49.937 4576-4606/edu.test.demo D/Test-TAG: zip 1,one
2022-08-01 11:29:49.937 4576-4606/edu.test.demo D/Test-TAG: zip 2,two
分析:
  • 可以看出zip將兩個(gè)flow的值進(jìn)行了一一組合。
  • 另外也可以看出只打印出了兩對值氢烘,因?yàn)榈谝粋€(gè)flow只有兩個(gè)值怀偷,所以在兩對結(jié)束之后zip已經(jīng)結(jié)束。
2. merge 是將兩個(gè)flow合并起來威始,將每個(gè)值依次發(fā)出來
代碼如下:
            val flow1  = listOf(1,2).asFlow()
            val flow2 = listOf("one","two","three").asFlow()
            merge(flow1,flow2).collect {value->
                Log.d(TAG.TAG,value.toString())
            }

日志如下:
2022-08-01 11:33:14.765 4636-4662/edu.test.demo D/Test-TAG: 1
2022-08-01 11:33:14.765 4636-4662/edu.test.demo D/Test-TAG: 2
2022-08-01 11:33:14.765 4636-4662/edu.test.demo D/Test-TAG: one
2022-08-01 11:33:14.765 4636-4662/edu.test.demo D/Test-TAG: two
2022-08-01 11:33:14.765 4636-4662/edu.test.demo D/Test-TAG: three
分析:
  • 可以看出merge在將flow1和flow2合并之后將五個(gè)值依次發(fā)送出來枢纠。
3. combine、combineTransform黎棠,combine是組合每個(gè)流最新的值晋渺,combineTransform為combine+transform。
代碼如下:
            val flow1  = flow {
                repeat(3){
                    delay(50)
                    emit(it)
                }
            }
            val flow2 = flow<String> {
                delay(100)
                emit("one")
                delay(100)
                emit("two")
            }
            flow1.combine(flow2){value1,value2->
                "combine $value1,$value2"
            }.collect {
                Log.d(TAG.TAG,it)
            }
            flow1.combineTransform(flow2){value1,value2->
                emit("combineTransform $value1,$value2")
            }.collect {
                Log.d(TAG.TAG,it)
            }
日志如下:
2022-08-01 11:47:13.049 5525-5552/edu.test.demo D/Test-TAG: combine 0,one
2022-08-01 11:47:13.063 5525-5553/edu.test.demo D/Test-TAG: combine 1,one
2022-08-01 11:47:13.114 5525-5552/edu.test.demo D/Test-TAG: combine 2,one
2022-08-01 11:47:13.152 5525-5553/edu.test.demo D/Test-TAG: combine 2,two
2022-08-01 11:47:13.256 5525-5551/edu.test.demo D/Test-TAG: combineTransform 0,one
2022-08-01 11:47:13.258 5525-5551/edu.test.demo D/Test-TAG: combineTransform 1,one
2022-08-01 11:47:13.310 5525-5551/edu.test.demo D/Test-TAG: combineTransform 2,one
2022-08-01 11:47:13.357 5525-5551/edu.test.demo D/Test-TAG: combineTransform 2,two
分析:
  • 可以看出combine將flow1與flow2的值進(jìn)行了組合脓斩,但是可以看到two只組合打印了一次木西,這是因?yàn)樵?,1,2 發(fā)送的時(shí)候,two都還沒發(fā)送随静,所以flow2的最新值都是one八千。
  • combineTransform 可以實(shí)現(xiàn)類似的效果,也可以進(jìn)行其他的操作燎猛,具體可以參照transform恋捆。
4. flattenConcat、flattenMerge重绷,flattenConcat將多個(gè)flow展平沸停,通俗點(diǎn)講,減少層級昭卓,flattenMerge和flattenConcat類似愤钾,但是可以設(shè)置并發(fā)數(shù)瘟滨。
代碼如下:
          val flow1 = (1..5).asFlow()
          val flow2 = flowOf("一","二","三","四","五")
            flowOf(flow1,flow2).flattenConcat().collect {
                Log.d(TAG.TAG,"flattenConcat $it")
            }
            flowOf(flow1,flow2).flattenMerge(2).collect {
                Log.d(TAG.TAG,"flattenMerge $it")
            }
日志如下:
2022-08-01 13:44:53.938 6409-6435/edu.test.demo D/Test-TAG: flattenConcat 1
2022-08-01 13:44:53.938 6409-6435/edu.test.demo D/Test-TAG: flattenConcat 2
2022-08-01 13:44:53.938 6409-6435/edu.test.demo D/Test-TAG: flattenConcat 3
2022-08-01 13:44:53.938 6409-6435/edu.test.demo D/Test-TAG: flattenConcat 4
2022-08-01 13:44:53.939 6409-6435/edu.test.demo D/Test-TAG: flattenConcat 5
2022-08-01 13:44:53.939 6409-6435/edu.test.demo D/Test-TAG: flattenConcat 一
2022-08-01 13:44:53.939 6409-6435/edu.test.demo D/Test-TAG: flattenConcat 二
2022-08-01 13:44:53.939 6409-6435/edu.test.demo D/Test-TAG: flattenConcat 三
2022-08-01 13:44:53.939 6409-6435/edu.test.demo D/Test-TAG: flattenConcat 四
2022-08-01 13:44:53.939 6409-6435/edu.test.demo D/Test-TAG: flattenConcat 五
2022-08-01 13:44:53.981 6409-6435/edu.test.demo D/Test-TAG: flattenMerge 1
2022-08-01 13:44:53.981 6409-6435/edu.test.demo D/Test-TAG: flattenMerge 一
2022-08-01 13:44:53.981 6409-6435/edu.test.demo D/Test-TAG: flattenMerge 二
2022-08-01 13:44:53.982 6409-6435/edu.test.demo D/Test-TAG: flattenMerge 三
2022-08-01 13:44:53.982 6409-6435/edu.test.demo D/Test-TAG: flattenMerge 四
2022-08-01 13:44:53.982 6409-6435/edu.test.demo D/Test-TAG: flattenMerge 五
2022-08-01 13:44:53.982 6409-6435/edu.test.demo D/Test-TAG: flattenMerge 2
2022-08-01 13:44:53.982 6409-6435/edu.test.demo D/Test-TAG: flattenMerge 3
2022-08-01 13:44:53.982 6409-6435/edu.test.demo D/Test-TAG: flattenMerge 4
2022-08-01 13:44:53.982 6409-6435/edu.test.demo D/Test-TAG: flattenMerge 5

分析:
  • 是不是看起來區(qū)別不大,都是將兩層變成了異常能颁,即展開杂瘸、鋪平,flattenConcat 是按順序執(zhí)行展平的伙菊,flattenMerge 設(shè)置參數(shù)為2之后則兩個(gè)是并發(fā)執(zhí)行的败玉,可以看到結(jié)果先打印了一個(gè)1,再是大寫一二三四五镜硕,然后是2345绒怨,當(dāng)然這也不是一成不變的,也可能是其他的谦疾,也可能按順序南蹂,因?yàn)槭遣l(fā)執(zhí)行的。
5. flatMapConcat念恍、flatMapMerge六剥、flatMapLatest,這三個(gè)看起來比較類似峰伙,卻別在于疗疟,flatMapConcat將元素轉(zhuǎn)換成flow然后展平,flatMapMerge則在flatMapConcat的基礎(chǔ)上可以設(shè)置并發(fā)數(shù)瞳氓,則類似于collectLatest策彤,展平最新的值。
代碼如下:
            (1..5).asFlow().flatMapConcat {
                flowOf(it)
            }.collect {
                Log.d(TAG.TAG, "flatMapConcat $it")
            }
            (1..5).asFlow().flatMapMerge(5) {
                flowOf(it)
            }.collect {
                Log.d(TAG.TAG, "flatMapMerge $it")
            }
            (1..5).asFlow().flatMapLatest {
                delay(100)
                flowOf(it)
            }.collect {
                Log.d(TAG.TAG, "flatMapLatest $it")
            }
日志如下:
2022-08-01 14:00:36.995 7281-7307/edu.test.demo D/Test-TAG: flatMapConcat 1
2022-08-01 14:00:36.995 7281-7307/edu.test.demo D/Test-TAG: flatMapConcat 2
2022-08-01 14:00:36.995 7281-7307/edu.test.demo D/Test-TAG: flatMapConcat 3
2022-08-01 14:00:36.995 7281-7307/edu.test.demo D/Test-TAG: flatMapConcat 4
2022-08-01 14:00:36.995 7281-7307/edu.test.demo D/Test-TAG: flatMapConcat 5
2022-08-01 14:00:37.036 7281-7307/edu.test.demo D/Test-TAG: flatMapMerge 1
2022-08-01 14:00:37.036 7281-7307/edu.test.demo D/Test-TAG: flatMapMerge 2
2022-08-01 14:00:37.036 7281-7307/edu.test.demo D/Test-TAG: flatMapMerge 4
2022-08-01 14:00:37.036 7281-7307/edu.test.demo D/Test-TAG: flatMapMerge 5
2022-08-01 14:00:37.038 7281-7307/edu.test.demo D/Test-TAG: flatMapMerge 3
2022-08-01 14:00:37.161 7281-7307/edu.test.demo D/Test-TAG: flatMapLatest 5
分析:
  • 可以看出flatMapConcat是按順序進(jìn)行map+展平操作匣摘。
  • flatMapMerge設(shè)置并發(fā)數(shù)之后順序不確定店诗。
  • flatMapLatest因?yàn)樵陂]包內(nèi)設(shè)置了延時(shí),所以只收集到了最新的值5音榜。

回調(diào)操作符

1. onStart庞瘸、onCompletion 這個(gè)很好理解,開始和結(jié)束赠叼。
代碼如下:
            (1..5).asFlow().onStart {
                Log.d(TAG.TAG,"onStart")
            }.onCompletion {
                Log.d(TAG.TAG,"onCompletion")
            }.collect {
                Log.d(TAG.TAG,"collect is $it")
            }
日志如下:
2022-08-01 14:11:46.202 7384-7411/edu.test.demo D/Test-TAG: onStart
2022-08-01 14:11:46.203 7384-7411/edu.test.demo D/Test-TAG: collect is 1
2022-08-01 14:11:46.203 7384-7411/edu.test.demo D/Test-TAG: collect is 2
2022-08-01 14:11:46.203 7384-7411/edu.test.demo D/Test-TAG: collect is 3
2022-08-01 14:11:46.203 7384-7411/edu.test.demo D/Test-TAG: collect is 4
2022-08-01 14:11:46.204 7384-7411/edu.test.demo D/Test-TAG: collect is 5
2022-08-01 14:11:46.204 7384-7411/edu.test.demo D/Test-TAG: onCompletion
2. catch 處理異常擦囊,也可以重新emit值。
代碼如下:
          flow {
                emit(1)
                throw IllegalArgumentException("exception throw")
                emit(2)
            }.catch {
                emit(-1)
                Log.e(TAG.TAG,"exception is $it")
            }.collect {
                Log.d(TAG.TAG,"collect is $it")
            }
日志如下:
2022-08-01 14:17:20.843 7465-7491/edu.test.demo D/Test-TAG: collect is 1
2022-08-01 14:17:20.844 7465-7491/edu.test.demo D/Test-TAG: collect is -1
2022-08-01 14:17:20.844 7465-7491/edu.test.demo E/Test-TAG: exception is java.lang.IllegalArgumentException: exception throw
分析:
  • 可以看出catch捕獲到了我們在flow中拋出的IllegalArgumentException異常嘴办,并且重新發(fā)送了特定值-1也被collect接收到了瞬场。
  • emit(2)在拋出異常之后沒有繼續(xù)執(zhí)行。
3. onEmpty 在flow為空的時(shí)候會回調(diào)
代碼如下:
             flow<Int> {
            }.onEmpty {
                Log.d(TAG.TAG, "onEmpty")
            }.collect {
                Log.d(TAG.TAG, "collect is $it")
            }
日志如下:
2022-08-01 14:22:01.544 7598-7625/edu.test.demo D/Test-TAG: onEmpty
4. onEach 是在每次collect之前調(diào)用涧郊。
代碼如下:
            flow<Int> {
                emit(1)
                emit(2)
                emit(3)
            }.onEach {
                Log.d(TAG.TAG, "onEach $it")
            }.collect {
                Log.d(TAG.TAG, "collect is $it")
            }

日志如下:
2022-08-01 14:26:11.313 8010-8035/edu.test.demo D/Test-TAG: onEach 1
2022-08-01 14:26:11.313 8010-8035/edu.test.demo D/Test-TAG: collect is 1
2022-08-01 14:26:11.313 8010-8035/edu.test.demo D/Test-TAG: onEach 2
2022-08-01 14:26:11.313 8010-8035/edu.test.demo D/Test-TAG: collect is 2
2022-08-01 14:26:11.313 8010-8035/edu.test.demo D/Test-TAG: onEach 3
2022-08-01 14:26:11.314 8010-8035/edu.test.demo D/Test-TAG: collect is 3

總結(jié)

  • 本篇主要介紹了兩個(gè)部分操作符贯被,分別為合并操作符和回調(diào)操作符。
  • 合并操作符,主要實(shí)現(xiàn)多個(gè)flow的一些合并刃榨、展平等操作;回調(diào)操作符双仍,主要在flow執(zhí)行的特定階段回調(diào)展示或處理操作枢希。
  • 本篇為自己學(xué)習(xí)及使用過程中的總結(jié),難免存在錯(cuò)誤或思維局限朱沃,歡迎大家討論指正苞轿。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市逗物,隨后出現(xiàn)的幾起案子搬卒,更是在濱河造成了極大的恐慌,老刑警劉巖翎卓,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件契邀,死亡現(xiàn)場離奇詭異,居然都是意外死亡失暴,警方通過查閱死者的電腦和手機(jī)坯门,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來逗扒,“玉大人古戴,你說我怎么就攤上這事【丶纾” “怎么了现恼?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長黍檩。 經(jīng)常有香客問我叉袍,道長,這世上最難降的妖魔是什么刽酱? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任畦韭,我火速辦了婚禮,結(jié)果婚禮上肛跌,老公的妹妹穿的比我還像新娘艺配。我一直安慰自己,他們只是感情好衍慎,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布转唉。 她就那樣靜靜地躺著,像睡著了一般稳捆。 火紅的嫁衣襯著肌膚如雪赠法。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機(jī)與錄音砖织,去河邊找鬼款侵。 笑死,一個(gè)胖子當(dāng)著我的面吹牛侧纯,可吹牛的內(nèi)容都是我干的新锈。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼眶熬,長吁一口氣:“原來是場噩夢啊……” “哼妹笆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起娜氏,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤拳缠,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后贸弥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窟坐,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年绵疲,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了狸涌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡最岗,死狀恐怖帕胆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情般渡,我是刑警寧澤懒豹,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站驯用,受9級特大地震影響脸秽,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蝴乔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一记餐、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧薇正,春花似錦片酝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至猴仑,卻和暖如春审轮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工疾渣, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留篡诽,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓榴捡,卻偏偏與公主長得像杈女,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子薄疚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354