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

如何监听Kotlin MutableList的元素变更并执行指定函数?

监听MutableList增删操作并执行指定函数的方案

针对你的需求,这里提供几种可行的实现方式,同时回答你关于可观察可变列表的问题:

一、自定义封装MutableList(轻量无依赖)

自己写一个类包装原生的MutableList,重写所有会修改列表的方法,在实际完成增删操作后触发foo函数:

class ObservableMutableList<T>(private val delegate: MutableList<T> = mutableListOf()) : MutableList<T> by delegate {
    // 重写所有修改列表的方法,触发foo
    override fun add(element: T): Boolean {
        val success = delegate.add(element)
        if (success) foo()
        return success
    }

    override fun add(index: Int, element: T) {
        delegate.add(index, element)
        foo()
    }

    override fun addAll(elements: Collection<T>): Boolean {
        val success = delegate.addAll(elements)
        if (success) foo()
        return success
    }

    override fun addAll(index: Int, elements: Collection<T>): Boolean {
        val success = delegate.addAll(index, elements)
        if (success) foo()
        return success
    }

    override fun remove(element: T): Boolean {
        val success = delegate.remove(element)
        if (success) foo()
        return success
    }

    override fun removeAt(index: Int): T {
        val removed = delegate.removeAt(index)
        foo()
        return removed
    }

    override fun removeAll(elements: Collection<T>): Boolean {
        val success = delegate.removeAll(elements)
        if (success) foo()
        return success
    }

    override fun retainAll(elements: Collection<T>): Boolean {
        val success = delegate.retainAll(elements)
        if (success) foo()
        return success
    }

    override fun clear() {
        if (delegate.isNotEmpty()) {
            delegate.clear()
            foo()
        }
    }
}

// 使用方式
var questionPool: MutableList<String> = ObservableMutableList()

这种方式的优势是不需要依赖任何第三方库,完全自定义触发逻辑,只有当列表确实被修改时才会调用foo。

二、用Kotlin StateFlow实现可观察列表(适合协程场景)

如果你的项目用了协程,可以用MutableStateFlow包裹列表,通过更新StateFlow来触发监听,进而执行foo:

import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.GlobalScope

// 内部可变的StateFlow,外部暴露只读版本
private val _questionPool = MutableStateFlow(mutableListOf<String>())
val questionPool = _questionPool.asStateFlow()

// 启动协程监听列表变化,触发foo
init {
    GlobalScope.launch {
        questionPool.collect {
            foo()
        }
    }
}

// 封装增删方法,必须通过更新StateFlow触发监听
fun addQuestion(id: String) {
    val newList = _questionPool.value.toMutableList()
    if (newList.add(id)) {
        _questionPool.value = newList
    }
}

fun removeQuestion(id: String) {
    val newList = _questionPool.value.toMutableList()
    if (newList.remove(id)) {
        _questionPool.value = newList
    }
}

这种方式适合需要异步处理列表变化的场景,还能在collect中对比前后列表的差异,做更复杂的逻辑处理。注意要根据实际业务管理协程的生命周期,避免内存泄漏。

三、Android平台专属:ObservableArrayList

如果你是在Android项目中开发,可以直接用系统提供的ObservableArrayList,它自带列表变化监听器:

import android.databinding.ObservableArrayList
import android.databinding.ObservableList

val questionPool: ObservableList<String> = ObservableArrayList()

// 添加列表变化监听器,触发foo
questionPool.addOnListChangedCallback(object : ObservableList.OnListChangedCallback<ObservableList<String>>() {
    override fun onChanged(sender: ObservableList<String>?) = foo()
    override fun onItemRangeChanged(sender: ObservableList<String>?, positionStart: Int, itemCount: Int) = foo()
    override fun onItemRangeInserted(sender: ObservableList<String>?, positionStart: Int, itemCount: Int) = foo()
    override fun onItemRangeMoved(sender: ObservableList<String>?, fromPosition: Int, toPosition: Int, itemCount: Int) = foo()
    override fun onItemRangeRemoved(sender: ObservableList<String>?, positionStart: Int, itemCount: Int) = foo()
})

这种方案不需要自己封装方法,适合Android数据绑定的场景,系统会自动在列表增删改移时触发对应的回调。

关于可观察可变列表的说明

原生Kotlin标准库并没有提供现成的可观察MutableList,但可以通过上面几种方式实现:要么自己封装拦截修改操作,要么用数据流(StateFlow)包裹列表,Android平台则有官方的ObservableList实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 11:43:20