Home > front end >  Key-value store with only explicitly allowed keys
Key-value store with only explicitly allowed keys

Time:08-04

I need a key-value store (e.g. a Mapor a custom class) which only allows keys out of a previously defined set, e.g. only the keys ["apple", "orange"]. Is there anything like this built-in in Kotlin? Otherwise, how could one do this? Maybe like the following code?

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()
}

CodePudding user response:

The best solution for your problem would be to use an enum, which provides exactly the functionality that you're looking for. According to the docs, you can declare an enum like so:

enum class AllowedKeys {
    APPLE, ORANGE
}

then, you could declare the keys with your enum!

CodePudding user response:

Since the keys are known at compile time, you could simply use an enum instead of String as the keys of a regular Map:

enum class Fruit {
    APPLE, ORANGE
}

val fruitMap = mutableMapOf<Fruit, String>()

Instead of Any, use whatever type you need for your values, otherwise it's not convenient to use.

If the types of the values depend on the key (a heterogeneous map), then I would first seriously consider using a regular class with your "keys" as properties. You can access the list of properties via reflection if necessary.

Another option is to define a generic key class, so the get function returns a type that depends on the type parameter of the key (see how CoroutineContext works in Kotlin coroutines).

CodePudding user response:

For reference, it's possible to do this if you don't know the set of keys until runtime. But it involves writing quite a bit of code; I don't think there's an easy way.

(I wrote my own Map class for this. We needed a massive number of these maps in memory, each with the same 2 or 3 keys, so I ended up writing a Map implementation pretty much from scratch: it used a passed-in array of keys — so all maps could share the same key array — and a private array of values, the same size. The code was quite long, but pretty simple. Most operations meant scanning the list of keys to find the right index, so the theoretic performance was dire; but since the list was always extremely short, it performed really well in practice. And it saved GBs of memory compared to using HashMap. I don't think I have the code any more, and it'd be far too long to post here, but I hope the idea is interesting.)

  • Related