Kotlin Flow 是 Kotlin 编程语言中的一个强大特性,用于处理异步数据流。它是 Kotlin 协程库的一部分,旨在以声明式和响应式的方式处理异步数据流。Flow 的设计与协程无缝集成,使得异步编程更加简单和直观。
suspend fun main() {
// 创建Flow的几种方法
val flow = flow {
emit(1)
emit(2)
emit(3)
emit(4)
emit(5)
}.collect {
println(it) // 打印1 2 3 4 5 共5行
}
val flow2 = flowOf(1, 2, 3, 4, 5)
flow2.collect {
println(it) // 打印1 2 3 4 5 共5行
}
val flow3 = listOf(1, 2, 3).asFlow();
flow3.collect {
println(it) // 打印1 2 3 共3行
}
val flow4 = channelFlow {
send(1)
send(2)
send(3)
send(4)
send(5)
}
flow4.collect {
println(it) // 打印1 2 3 4 5 共5行
}
// 获取第一个和最后一个元素
val firstValue = flow4.first()
println(firstValue) // 打印1
val lastValue = flow4.last()
println(lastValue) // 打印5
//3.Flow的操作符
// 3.1 map 操作符 将Flow中的每个元素进行转换
val flow5 = flowOf(1, 2, 3, 4, 5)
flow5.map {
it * 3 //无效
it * 5 //无效
it * 10// 有效以最后一行为准注意与trans的区别
}.collect {
println(it) // 打印10 20 30 40 50 共5行
}
// 3.2 trans 操作符 将Flow中的每个元素进行转换
val flow6 = flowOf(1, 2, 3)
flow6.transform {
emit(it * 3) //有效
emit(it * 5) //有效
}.collect {
println(it) // 打印3 5 6 10 9 15 共6行 注意与map的区别
}
// 3.3 filter 操作符 过滤Flow中符合条件的元素
val flow7 = flowOf(1, 2, 3, 4, 5, 6)
flow7.filter {
it % 3 == 0
}.collect {
println(it) //打印 3 6 共2行
}
// take 操作符 取Flow中的前n个元素
val flow8 = flowOf(1, 2, 3, 4, 5, 6)
flow8.take(3).collect {
println(it) //打印 1 2 3 共3行
}
//3.4 组合操作符 zip 将2个Flow的值按顺序组合
val flow9 = flowOf(1, 2, 3)
val flow10 = flowOf("a", "b", "c")
flow9.zip(flow10) { it1, it2 ->
"$it1$it2" //将两个Flow的值按顺序组合
}.collect {
println(it) //打印 1a 2b 3c 共3行
}
println("=================================")
//3.5 组合操作符 combine 将多个 Flow 的最新值组合,有可能不是按顺序,比如:
// 1a
//2b
//2c
//3c
//使用runBlocking运行
runBlocking {
val flow11 = flowOf(1, 2, 3)
val flow12 = flowOf("a", "b", "c")
flow11.combine(flow12) { it1, it2 ->
"$it1$it2" //将两个Flow的值按顺序组合
}.collect {
println(it) //打印 1a 2b 3c 共3行
}
}
//3.6 flatMapConcat 扁平化操作符 按顺序将每个值转换为 Flow 并连接
val flow13 = flowOf(1, 2, 3)
flow13.flatMapConcat { it -> flowOf(it, it * 2, it * 3) }.collect {
println(it) //打印 1 2 3 2 4 6 3 6 9 共9行 与transform有点类似
}
//3.7 flatMapMerge 扁平化操作符 并发将每个值转换为 Flow 并连接
val flow14 = flowOf(1, 2, 3)
flow14.flatMapMerge { it -> flowOf(it, it * 2, it * 3) }.collect {
println(it) //打印 1 2 3 2 4 6 3 6 9 或者 369246123共9行 与transform有点类似
}
//3.8 flatMapLatest 扁平化操作符 只处理最新的值,取消之前的转换
val flow15 = flowOf(1, 2, 3)
flow15.flatMapLatest { it -> flowOf(it, it * 2, it * 3) }.collect {
println(it) // 打印 1 2 3 2 4 6 3 6 9
}
//3.9 flatMapLatest 扁平化操作符 只处理最新的值,取消之前的转换 ?
val flow16 = flowOf(1, 2, 3)
flow16.flatMapLatest { it -> flowOf(it, it * 2, it * 3) }.collect {
println(it) //
}
// 4. Flow 的冷流与热流
// 4.1 冷流(Cold Stream)
// Flow 是冷流,只有在被收集时才会执行。
// 每次收集都会重新执行 Flow 的代码。
// 示例:
val flow17 = flow {
println("Flow start...")
emit(1)
emit(2)
}
flow17.collect {
println("Collect : $it") // Flow start... Collect : 1 Collect : 2 共三行
}
flow17.collect {
println("Collect : $it") // Flow start... Collect : 1 Collect : 2 共三行
}
// 4.2 热流(Hot Stream)
// Kotlin 中的 StateFlow 是热流的实现
// 热流是预先启动的,可以在收集之前就开始执行。
// 热流可以被多个收集者共享。
// 示例:
val stateFlow = MutableStateFlow(0)
stateFlow.value = 1
stateFlow.value = 2
stateFlow.value = 3
stateFlow.collect {
println("Collect : $it") // Collect : 3
}
}
// 模拟网络请求
suspend fun main() {
// 模拟网络请求
fun requestNetwork(): Flow<Int> = flow {
repeat(3) {
delay(1000)
emit(it)
}
}
requestNetwork().collect { println(it) } //打印 0 1 2 共3行
}
总结
Kotlin Flow 是一个强大的工具,用于处理异步数据流。它的核心优势包括:
冷流模型:按需执行,节省资源。
丰富的操作符:支持复杂的数据流处理。
与协程无缝集成:简化异步编程。
通过 Flow,你可以以声明式的方式编写异步代码,同时享受 Kotlin 协程带来的简洁性和高效性。如果你需要处理连续的数据流,Flow 是一个非常值得学习和使用的工具!