Kotlin Flow中间操作符:转换后值相同时如何避免发射?
秒表Flows多精度监听去重方案
核心解决方法就是在每个观察者的map转换后,加上distinctUntilChanged()操作符——它会自动过滤掉和上一次相同的发射值,只有当转换后的精度数值真的变化时,才会通知观察者。这样既能保留原始耗时的根Flow,又能让不同观察者自由定制精度,还不会收到重复输出。
代码示例
首先定义记录原始毫秒级耗时的根Flow:
// 根Flow:存储原始耗时(单位:毫秒) val rawElapsedTimeFlow = MutableStateFlow(0L) // 模拟秒表计时逻辑:每100毫秒更新一次原始耗时 fun startStopwatch() { val startTime = System.currentTimeMillis() CoroutineScope(Dispatchers.Default).launch { while (true) { delay(100) rawElapsedTimeFlow.value = System.currentTimeMillis() - startTime } } }
然后给不同精度的观察者添加处理逻辑:
// 秒级精度监听:仅整秒变化时输出 CoroutineScope(Dispatchers.Main).launch { rawElapsedTimeFlow .map { it / 1000 } // 转换为秒级整数 .distinctUntilChanged() // 过滤重复值 .collect { seconds -> println("秒级更新:$seconds 秒") } } // 0.1秒精度监听:仅0.1秒区间变化时输出 CoroutineScope(Dispatchers.Main).launch { rawElapsedTimeFlow .map { it / 100.0 } // 转换为0.1秒精度的浮点数 .distinctUntilChanged() // 过滤重复值 .collect { tenths -> println("0.1秒级更新:$tenths 秒") } }
补充说明
- 如果转换后是浮点数,担心精度误差导致不必要的发射,可以自定义
distinctUntilChanged的判断逻辑,比如:.distinctUntilChanged { old, new -> // 自定义判断:差值小于0.01则视为相同值 kotlin.math.abs(old - new) < 0.01 } - 不管是
StateFlow这类热Flow,还是用flowbuilder创建的冷Flow,这个方案都适用,只需要在精度转换的map之后加上去重操作符即可。
内容的提问来源于stack exchange,提问作者BPDev
相关产品推荐
相关产品推荐

