只包含显式允许的键的键值存储



我需要一个键值存储(例如Map或自定义类(,它只允许以前定义的集合中的键,例如只允许键["apple", "orange"]。Kotlin内置了这样的东西吗?否则,怎么会这样呢?也许喜欢下面的代码?

class KeyValueStore(val allowedKeys: List<String>){
private val map = mutableMapOf<String,Any>()
fun add(key: String, value: Any) {
if(!allowedKeys.contains(key))
throw Exception("key $key not allowed")
map.put(key, value)
}
// code for reading keys, like get(key: String) and getKeys()
}

您的问题的最佳解决方案是使用枚举,它正好提供了您想要的功能。根据文档,您可以声明这样的枚举:

enum class AllowedKeys {
APPLE, ORANGE
}

然后,您可以用enum声明密钥!

由于密钥在编译时是已知的,因此可以简单地使用枚举而不是String作为常规Map:的密钥

enum class Fruit {
APPLE, ORANGE
}
val fruitMap = mutableMapOf<Fruit, String>()

不要使用Any,而是使用值所需的任何类型,否则使用起来就不方便了。

如果值的类型取决于键(异构映射(,那么我首先会认真考虑使用一个带有"的正则类;键";作为属性。如有必要,可以通过反射访问特性列表。

另一个选项是定义一个泛型键类,因此get函数返回一个依赖于键的类型参数的类型(请参阅CoroutineContext在Kotlin协程中的工作方式(。

作为参考,如果您在运行时之前还不知道密钥集,则可以这样做。但它涉及到编写相当多的代码;我认为没有简单的方法。

(我为此编写了自己的Map类。我们在内存中需要大量这样的映射,每个映射都有相同的2或3个键,所以我最终几乎从头开始编写了一个Map实现:它使用了一个传入的键数组,这样所有映射都可以共享相同的键数组和一个大小相同的值的私有数组。代码很长,但很简单。大多数操作都意味着扫描键列表以找到正确的索引,因此理论性能很差;但由于名单总是很短,所以它在实践中表现得很好。与使用HashMap相比,它节省了GB的内存。我想我已经没有代码了,在这里发布太长了,但我希望这个想法很有趣。(

最新更新