我有一张 map ,在我的例子中是 ConcurrentHashMap<String, Device>
在 websocket 上接收某些事件时正在更新。我想在这个 map 上实现一个 observable,以了解何时添加、更新或删除条目。我试过 ObservableProperty
但 map 更改时不会调用任何方法。
var deviceCache : ConcurrentHashMap<String, Device> by MyObservable(ConcurrentHashMap())
class MyObservable<T, V>(initialValue: ConcurrentHashMap<T, V>) : ObservableProperty<ConcurrentHashMap<T, V>>(initialValue) {
override fun afterChange(property: KProperty<*>, oldValue: ConcurrentHashMap<T, V>, newValue: ConcurrentHashMap<T, V>) {
super.afterChange(property, oldValue, newValue)
log.e("new value is $newValue")
}
override fun beforeChange(property: KProperty<*>, oldValue: ConcurrentHashMap<T, V>, newValue: ConcurrentHashMap<T, V>): Boolean {
log.e("beforeChange called")
return super.beforeChange(property, oldValue, newValue)
}
}
谁能帮我解决这个问题?
最佳答案
问题是 Map
不是属性,您不能以这种方式使用属性委托(delegate)。你要做的就是为 Map
写一个装饰器。像这样:
class ObservableMap<K, V>(private val map: MutableMap<K, V>) : MutableMap<K, V> by map {
override fun put(key: K, value: V): V? {
TODO("not implemented")
}
override fun putAll(from: Map<out K, V>) {
TODO("not implemented")
}
override fun remove(key: K): V? {
TODO("not implemented")
}
}
这里我们将所有操作委托(delegate)给后台
map
在上述方法中添加/删除时,您只需要实现您的逻辑。我不确定您所说的
update
是什么意思但是如果你的意思是“ map 中的一个值被覆盖”,那么你可以在 put
中处理它。 .你可以用这个
ObservableMap
像这样:val map = ObservableMap(ConcurrentHashMap<String, String>())
注意如果要支持
ConcurrentHashMap
的操作您还需要包含 overrides
对于 AbstractMap<K,V>
和 ConcurrentMap<K,V>
因为他们添加了一些您可能想要跟踪的新操作。上面的代码只是一个例子。
关于dictionary - 可在 map 上观察以检测何时添加、更新或删除条目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56440641/