当前位置:网站首页>[Koltin Flow (2)] The end operator of the Flow operator
[Koltin Flow (2)] The end operator of the Flow operator
2022-07-30 05:59:00 【MakerGaoGao】
简介
- 本篇主要介绍flow的操作符部分,
- 想要了解flow的创建,可以参考上一篇【Koltin Flow(一)】五种创建flow的方式
- FlowOperators are mainly divided into terminal operators and intermediate operators,This article mainly introduces the terminal operator.
- This article will introduce the functions and usage of various operators,Of course there are more operators,Nor will it be fully covered,The end point will be selected for explanation.
末端操作符
The terminal operator is in flow处理的最后,主要用来接收数据,当然flowfor cold flow(这里不做展开,后面再说),The operation is performed only when the terminal operator is used,Usually received data is inseparable from the terminal operator.
- collect It was used in the five ways in the previous article,The characteristic is that the data sent earlier is received in turn.
- collectIndexed It will be included when receivingindex下标,Can be used to handle subscript-related requirements,
代码如下:
flowOf(1,2,3,4,5).collectIndexed {
index,value->
Log.d(TAG.TAG,"position[$index] it is $value")
}
日志如下:
2022-07-28 17:34:49.619 3842-3868/edu.test.demo D/Test-TAG: position[0] it is 1
2022-07-28 17:34:49.619 3842-3868/edu.test.demo D/Test-TAG: position[1] it is 2
2022-07-28 17:34:49.619 3842-3868/edu.test.demo D/Test-TAG: position[2] it is 3
2022-07-28 17:34:49.619 3842-3868/edu.test.demo D/Test-TAG: position[3] it is 4
2022-07-28 17:34:49.619 3842-3868/edu.test.demo D/Test-TAG: position[4] it is 5
- collectLatest When the data is too late to process, only the latest data will be saved,This involves back pressure(这里不做展开,后面讲解).
现象1,normal processing time and collect没什么区别,are always receiving data:
代码如下:
flowOf(1,2,3,4,5).collectLatest {
value->
Log.d(TAG.TAG,"it is $value")
}
日志如下:
2022-07-28 17:37:23.973 3903-3929/edu.test.demo D/Test-TAG: it is 1
2022-07-28 17:37:23.980 3903-3929/edu.test.demo D/Test-TAG: it is 2
2022-07-28 17:37:23.981 3903-3929/edu.test.demo D/Test-TAG: it is 3
2022-07-28 17:37:23.981 3903-3929/edu.test.demo D/Test-TAG: it is 4
2022-07-28 17:37:23.981 3903-3929/edu.test.demo D/Test-TAG: it is 5
现象2,When it is too late to process, only the latest data will be kept:
代码如下:
flowOf(1,2,3,4,5).collectLatest {
value->
delay(10)
Log.d(TAG.TAG,"it is $value")
}
日志如下:
2022-07-28 17:37:39.922 3959-3985/edu.test.demo D/Test-TAG: it is 5
- single、singleOrNull、first、firstOrNull,single及singleOrNullReceives a single value,区别是在flowThrows an exception if it is empty or if there is more than one value,但是singleOrNull只是返回null,并不会抛出异常.first、firstOrNullBoth receive the first value,区别是当flow为空时候,first会抛出异常,但是firstOrNull只是会返回null,并不会抛出异常.
代码如下:
val flow1 = flow {
emit(111)
}
val flow2 = flow {
emit(111)
emit(1110)
}
val flow3 = flow<String> {
}
launch {
Log.d(TAG.TAG, "single 1 data is ${
flow1.single()}")
Log.d(TAG.TAG, "singleOrNull 1 data is ${
flow1.singleOrNull()}")
kotlin.runCatching {
Log.d(TAG.TAG, "single 2 data is ${
flow2.single()}")
}.onFailure {
Log.e(TAG.TAG,"single 2 throwable is $it")
}
Log.d(TAG.TAG, "singleOrNull 2 data is ${
flow2.singleOrNull()}")
Log.d(TAG.TAG, "first 2 data is ${
flow2.first()}")
Log.d(TAG.TAG, "firstOrNull 2 data is ${
flow2.firstOrNull()}")
kotlin.runCatching {
Log.d(TAG.TAG, "first 3 data is ${
flow3.first()}")
}.onFailure {
Log.e(TAG.TAG,"first 3 throwable is $it")
}
Log.d(TAG.TAG, "firstOrNull 3 data is ${
flow3.firstOrNull()}")
}
日志如下:
2022-07-29 10:04:02.767 5737-5763/edu.test.demo D/Test-TAG: single 1 data is 111
2022-07-29 10:04:02.768 5737-5763/edu.test.demo D/Test-TAG: singleOrNull 1 data is 111
2022-07-29 10:04:02.769 5737-5763/edu.test.demo E/Test-TAG: single 2 throwable is java.lang.IllegalArgumentException: Flow has more than one element
2022-07-29 10:04:02.769 5737-5763/edu.test.demo D/Test-TAG: singleOrNull 2 data is null
2022-07-29 10:04:02.769 5737-5763/edu.test.demo D/Test-TAG: first 2 data is 111
2022-07-29 10:04:02.770 5737-5763/edu.test.demo D/Test-TAG: firstOrNull 2 data is 111
2022-07-29 10:04:02.770 5737-5763/edu.test.demo E/Test-TAG: first 3 throwable is java.util.NoSuchElementException: Expected at least one element
2022-07-29 10:04:02.770 5737-5763/edu.test.demo D/Test-TAG: firstOrNull 3 data is null
分析:
- 当flowwhen it is a value single 和singleOrNull 都是正常的,但是当flowWorth the time for twosingle抛出了异常single 2 throwable is java.lang.IllegalArgumentException: Flow has more than one element,而singleOrNull 返回为null,No exceptions were ruled out.
- 当flowwhen not empty,first和firstOrNull都是正常的,但是当flow为空,first抛出了异常first 3 throwable is java.util.NoSuchElementException: Expected at least one element,但是firstOrNull 返回为null,并没有抛出异常.
- reduce和fold,reduceis a cumulative operation,The initial value is the first value and the next value,foldIt is also a cumulative operation,The initial value is the initial value set and the first value.
代码如下:
val reduceData = (1..5).asFlow().reduce {
accumulator, value -> accumulator + value }
Log.d(TAG.TAG, "reduceData is $reduceData")
val foldData = (1..5).asFlow().fold(1000) {
acc, value -> acc + value }
Log.d(TAG.TAG, "foldData is $foldData")
val flow = flow<Int> {
}
kotlin.runCatching {
Log.d(TAG.TAG, "reduceEmptyData is ${
flow.reduce {
accumulator, value -> accumulator + value }}")
}.onFailure {
Log.e(TAG.TAG,"reduceEmptyData throwable is $it ")
}
Log.d(TAG.TAG, "foldEmptyData is ${
flow.fold(10) {
acc, value -> acc + value }}")
日志如下:
2022-07-29 10:45:24.808 6321-6346/edu.test.demo D/Test-TAG: reduceData is 15
2022-07-29 10:45:24.808 6321-6346/edu.test.demo D/Test-TAG: foldData is 1015
2022-07-29 10:45:24.810 6321-6346/edu.test.demo E/Test-TAG: reduceEmptyData throwable is java.util.NoSuchElementException: Empty flow can't be reduced
2022-07-29 10:45:24.810 6321-6346/edu.test.demo D/Test-TAG: foldEmptyData is 10
分析:
- 可以看出reduce是进行了1-5的累计,结果为15,而fold则是在1000的基础上再加上1-5的累加,结果为1015.
- Of course there are people who have doubts,If I don't write later accumulator, value -> accumulator + value ,和 acc, value -> acc + value ,Replacing the plus with minus line doesn't work,当然是可以的,reduce和foldJust do sequential accumulation,Just replacing it with a subtraction is not an accumulation operation,It's another operation.
- flow为空,reduce 会抛出异常 reduceEmptyData throwable is java.util.NoSuchElementException: Empty flow can’t be reduced,fold则返回初始值,不会抛出异常.
- toList和toSet,toList将flow转换成list结果,参数为mutableList,可传可不传,But be careful not to call it multiple times when passing parameters,The value will be added multiple times.toSet类似,但是toSetMultiple calls with an initial value passed in will not produce duplicate values,因为setIt is not repetitive in itself.
代码如下 :
//list
val flow = flow<Int> {
repeat(10){
delay(10)
emit(it)
}
}
Log.d(TAG.TAG,"flow.toList() is ${
flow.toList()}")
val lisDataInit = arrayListOf<Int>()
val listData = flow.toList(lisDataInit)
flow.toList(lisDataInit)
Log.d(TAG.TAG,"listData is $listData")
Log.d(TAG.TAG,"lisDataInit is $lisDataInit")
//set
val flow = flow<Int> {
repeat(10){
delay(10)
emit(it)
}
}
val setDataInit = LinkedHashSet<Int>()
Log.d(TAG.TAG,"flow.toSet() is ${
flow.toSet()}")
val setData = flow.toSet(setDataInit)
flow.toSet(setDataInit)
Log.d(TAG.TAG,"setDataInit is $setData")
Log.d(TAG.TAG,"setDataInit is $setDataInit")
日志如下:
2022-07-29 10:55:48.927 6810-6835/edu.test.demo D/Test-TAG: flow.toList() is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2022-07-29 10:55:49.157 6810-6835/edu.test.demo D/Test-TAG: listData is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2022-07-29 10:55:49.157 6810-6835/edu.test.demo D/Test-TAG: lisDataInit is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2022-07-29 11:00:30.678 6896-6922/edu.test.demo D/Test-TAG: flow.toSet() is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2022-07-29 11:00:30.908 6896-6922/edu.test.demo D/Test-TAG: setData is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
2022-07-29 11:00:30.908 6896-6922/edu.test.demo D/Test-TAG: setDataInit is [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
分析:
- 可以看出 toList直接将flowsent into list结果,toSetConvert the result directly to Set结果..
- 可以看出传入list多次调用,The value will be added multiple times,listData和lisDataInitIt is said that the data is added twice,这两个其实是一个list,set类似,但是setitself is not repetitive,So it won't produce the result of adding it multiple times.从源码可以看出,源码如下:
/** * Collects given flow into a [destination] */
public suspend fun <T> Flow<T>.toList(destination: MutableList<T> = ArrayList()): List<T> = toCollection(destination)
/** * Collects given flow into a [destination] */
public suspend fun <T> Flow<T>.toSet(destination: MutableSet<T> = LinkedHashSet()): Set<T> = toCollection(destination)
/** * Collects given flow into a [destination] */
public suspend fun <T, C : MutableCollection<in T>> Flow<T>.toCollection(destination: C): C {
collect {
value ->
destination.add(value)
}
return destination
}
总结
- This article mainly introduces the terminal operator,包含collect 、collectIndex、collectLatest 、single、singleOrNull、first、firstOrNull、 reduce、fold、toList、toSet等.
- The terminal operator is only used for data collection,如collectCollect in order,singlesingle collection,toList转换成list结果等.
- In fact, the operator itself is not difficult,As long as we use more,You can click the open source code to see more,In fact, it is easier to understand.
- This article is also summed up in the process of own learning and use,There are bound to be mistakes and limitations of thinking,I also hope that you will point out and communicate more.
边栏推荐
- 机器学习—梯度下降Gradient Descent Optimization—c语言实现
- postman 请求 post 调用 传 复合 json数据
- MYSQL-InnoDB的线程模型
- How MySQL to prepare SQL pretreatment (solve the query IN SQL pretreatment can only query out the problem of a record)
- curl (7) Failed connect to localhost8080; Connection refused
- JVM之GC 调优基础知识(一)
- MySQL基础(DDL、DML、DQL)
- Golang go-redis cluster模式下不断创建新连接,效率下降问题解决
- MySQL(3)
- Mysql8.+学习笔记
猜你喜欢
随机推荐
How MySQL to prepare SQL pretreatment (solve the query IN SQL pretreatment can only query out the problem of a record)
[GO语言基础] 一.为什么我要学习Golang以及GO语言入门普及
Detailed MySQL-Explain
成绩排序(华中科技大学考研机试题)(DAY 87)
75. 颜色分类
2022年SQL经典面试题总结(带解析)
SQL连接表(内连接、左连接、右连接、交叉连接、全外连接)
MySql模糊查询大全
个人博客系统(附源码)
[Redis Master Cultivation Road] Jedis - the basic use of Jedis
Seata exception: endpoint format should like ip:port
机器学习—梯度下降Gradient Descent Optimization—c语言实现
五一去见了一些身价数千万的成功人士,我一些新的思路和启示
剑指offer(刷题篇12)
是时候不得不学英语了,技多不压身,给自己多条路
MySQL stored procedure
MySQL索引常见面试题(2022版)
程序员赚钱实操,手把手教你做付费课程,自媒体,付费文章及付费技术课赚钱
[Koltin Flow (1)] Five ways to create flow
mysql basics (4)









