前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【Kotlin 协程】Flow 操作符 ② ( 末端操作符 | collect 操作符 | reduce 操作符 | single 操作符 | first 操作符 | toList 操作符 )

【Kotlin 协程】Flow 操作符 ② ( 末端操作符 | collect 操作符 | reduce 操作符 | single 操作符 | first 操作符 | toList 操作符 )

作者头像
韩曙亮
发布2023-03-30 18:31:00
9300
发布2023-03-30 18:31:00
举报
文章被收录于专栏:韩曙亮的移动开发专栏

文章目录

一、末端操作符


末端操作符 指的是 在 Flow 流最末端 调用 挂起函数 收集元素 的操作符 , 最常见的 末端操作符 就是 collect 操作符 ;

常见的末端操作符 :

  • 收集元素 : collect ;
  • 将收集的元素转为集合 : toList , toSet ;
  • 收集第一个元素 : first ;
  • 发射单个元素 : single ;
  • 规约流到单个值 : reduce , fold ;

1、collect 操作符

collect 操作符原型 :

代码语言:javascript
复制
/**
 * 终端流操作符,使用提供的[动作]收集给定的流。
 * 如果在收集过程中或在所提供的流中发生任何异常,则此方法将重新抛出此异常。
 *
 * 使用示例:
 *
 * ```
 * val flow = getMyEvents()
 * try {
 *     flow.collect { value ->
 *         println("Received $value")
 *     }
 *     println("My events are consumed successfully")
 * } catch (e: Throwable) {
 *     println("Exception from the flow: $e")
 * }
 * ```
 */
public suspend inline fun <T> Flow<T>.collect(crossinline action: suspend (value: T) -> Unit): Unit =
    collect(object : FlowCollector<T> {
        override suspend fun emit(value: T) = action(value)
    })

2、reduce 操作符

reduce 操作符原型 :

代码语言:javascript
复制
/**
 * 从第一个元素开始累加值,并对当前累加器值和每个元素应用[操作]。
 * 如果流为空,抛出[NoSuchElementException]。
 */
public suspend fun <S, T : S> Flow<T>.reduce(operation: suspend (accumulator: S, value: T) -> S): S {
    var accumulator: Any? = NULL

    collect { value ->
        accumulator = if (accumulator !== NULL) {
            @Suppress("UNCHECKED_CAST")
            operation(accumulator as S, value)
        } else {
            value
        }
    }

    if (accumulator === NULL) throw NoSuchElementException("Empty flow can't be reduced")
    @Suppress("UNCHECKED_CAST")
    return accumulator as S
}

代码示例 :

代码语言:javascript
复制
package kim.hsl.coroutine

import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        runBlocking {
            val result = (0..3)
                        .asFlow()
                        .reduce{a, b ->
                            a + b
                        }
            println("result : $result")
        }
    }
}

执行结果 :

代码语言:javascript
复制
2022-12-26 15:51:20.411 24364-24364/kim.hsl.coroutine I/System.out: result : 6
在这里插入图片描述
在这里插入图片描述

3、single 操作符

single 操作符原型 :

代码语言:javascript
复制
/**
 * 终端操作符,等待一个且仅等待一个值发出。
 * 为空流抛出[NoSuchElementException],为流抛出[IllegalStateException]
 * 包含多个元素的。
 */
public suspend fun <T> Flow<T>.single(): T {
    var result: Any? = NULL
    collect { value ->
        require(result === NULL) { "Flow has more than one element" }
        result = value
    }

    if (result === NULL) throw NoSuchElementException("Flow is empty")
    return result as T
}

4、first 操作符

first 操作符原型 :

代码语言:javascript
复制
/**
 * 终端操作符,返回流发出的第一个元素,然后取消流的收集。
 * 如果流为空,则抛出[NoSuchElementException]。
 */
public suspend fun <T> Flow<T>.first(): T {
    var result: Any? = NULL
    collectWhile {
        result = it
        false
    }
    if (result === NULL) throw NoSuchElementException("Expected at least one element")
    return result as T
}

5、fold 操作符

fold 操作符原型 :

代码语言:javascript
复制
/**
 * 从[initial]值开始累加值,并应用[operation]当前累加器值和每个元素
 */
public suspend inline fun <T, R> Flow<T>.fold(
    initial: R,
    crossinline operation: suspend (acc: R, value: T) -> R
): R {
    var accumulator = initial
    collect { value ->
        accumulator = operation(accumulator, value)
    }
    return accumulator
}

6、toList 操作符

toList 操作符原型 :

代码语言:javascript
复制
/**
 * 将给定的流收集到[destination]
 */
public suspend fun <T> Flow<T>.toList(destination: MutableList<T> = ArrayList()): List<T> = toCollection(destination)

7、toSet 操作符

toSet 操作符原型 :

代码语言:javascript
复制
/**
 * 将给定的流收集到[destination]
 */
public suspend fun <T> Flow<T>.toSet(destination: MutableSet<T> = LinkedHashSet()): Set<T> = toCollection(destination)
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 文章目录
  • 一、末端操作符
    • 1、collect 操作符
      • 2、reduce 操作符
        • 3、single 操作符
          • 4、first 操作符
            • 5、fold 操作符
              • 6、toList 操作符
                • 7、toSet 操作符
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档