You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,还是用flow builder创建的冷Flow,这个方案都适用,只需要在精度转换的map之后加上去重操作符即可。

内容的提问来源于stack exchange,提问作者BPDev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.19 13:07:19