0

need to call a api which take Map<String, String>

fun api.log(map: Map<string, String>

but the key has to be only from the registered ones, so defined a enum for the registered keys:

enum class RegisteredKey {
    NONE, ZOOM
}

and first build the EnumMap<> to enforce key type:

var enumParamMap: EnumMap<RegisteredKey, String> = EnumMap<RegisteredKey, String>(RegisteredKey::class.java)
    enumParamMap.put(RegisteredKeys.NONE, "0")
    enumParamMap.put(RegisteredKeys.ZOOM, "1")

doLog(enumParamMap)

question 1, is there constructor to build the enumMap directly with data?

and then need to transform the EnumMap into a Map<> so that the api.log() will accept it

fun doLog(enumParamMap: EnumMap<RegisteredKey, String>) {

    val map: MutableMap<String, String> = mutableMapOf()

    for (enum in enumParamMap.entries) {
        map.put(enum.key.name, enum.value)
    }
    api.log(map)
}

question 2: is there simpler way to map the enumMap to regular map?

1
  • 1
    Your question 2 is misleading because you don't just want a "regular map" but you want a map with different parameters than the original (you want the key to be of type String instead of RegisteredKey). Commented Oct 9, 2019 at 15:40

2 Answers 2

2

I'm not sure I'm interpreting your first question correctly, but if you mean you want to initialize an exhaustive EnumMap where every key has an entry, similar to the Array constructor that takes a lambda, you could write one like this:

inline fun <reified K : Enum<K>, V> exhaustiveEnumMap(init: (key: K) -> V): EnumMap<K, V> {
    val map = EnumMap<K, V>(K::class.java)
    for (key in enumValues<K>())
        map[key] = init(key)
    return map;
}

Usage:

val map = exhaustiveEnumMap<RegisteredKey, String> { key -> key.ordinal.toString() }

or

val map = exhaustiveEnumMap<RegisteredKey, String> { key -> 
    when (key){
        RegisteredKey.NONE -> "0"
        RegisteredKey.ZOOM -> "1"
    }
}

Edit based on your comment: You could do that by wrapping a mapOf call with the EnumMap constructor like this, but it would be instantiating an intermediate throwaway LinkedHashMap:

val map = EnumMap(mapOf(RegisteredKey.NONE to "0", RegisteredKey.ZOOM to "1"))

Instead, you could write a helper function like this:

inline fun <reified K: Enum<K>, V> enumMapOf(vararg pairs: Pair<K, V>): EnumMap<K, V> =
    pairs.toMap(EnumMap<K, V>(K::class.java))

Usage:

var enumParamMap = enumMapOf(RegisteredKey.NONE to "0", RegisteredKey.ZOOM to "1")

-------

For your next question, I'm not sure if this is really any simpler, but you could do:

fun doLog(enumParamMap: EnumMap<RegisteredKey, String>) =
    api.log(enumParamMap.map{ it.key.name to it.value }.toMap())

It's more concise, but you're allocating a list and some pairs that you wouldn't be with your way of doing it.

Sign up to request clarification or add additional context in comments.

2 Comments

for 1st I mean something like instantiate a regular map it could be done with Map<String, String>() {"a" to "1", "b" to "2"}
Someone commented a better way to convert the map on the other answer. fun doLog(enumParamMap: EnumMap<RegisteredKey, String>) = api.log(enumParamMap.mapKeys{ it.key.name })
1

Something like this should work for initialization:

EnumMap<RegisteredKey, String>(
    mapOf(RegisteredKey.NONE to "0", RegisteredKey.ZOOM to "1")
)

To get a normal map just call .toMutableMap():

EnumMap<RegisteredKey, String>(
    mapOf(RegisteredKey.NONE to "0", RegisteredKey.ZOOM to "1")
).toMutableMap()

2 Comments

This is not quite the same; the OP wants a Map<String, String> but you gave them a Map<RegisteredKey, String>. In fairness, the OP misled you by saying they wanted a "normal map" when in fact they wanted a map with different parameters.
use .mapKeys {it.key.name} instead of .toMutableMap()

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.