【Koltin Flow(一)】五种创建flow的方式
【Koltin Flow(二)】Flow操作符之末端操作符
【Koltin Flow(三)】Flow操作符之中间操作符(一)
【Koltin Flow(三)】Flow操作符之中间操作符(二)
【Koltin Flow(三)】Flow操作符之中间操作符(三)
【Koltin Flow(四)】Flow背压
【Koltin Flow(五)】SharedFlow及StateFlow
末端操作符在flow处理的最后,主要用来接收数据,当然flow为冷流(这里不做展开,后面再说),只有在末端操作符的时候才会执行操作,通常的接收数据都离不开末端操作符。
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
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,来不及处理的时候只会保持最新的数据:
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
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
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
//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]
/**
* 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
}