kotlin,如何将 EnumMap 转换为常规 Map

kotlin, how convert a EnumMap into regular Map

需要调用 api 需要 Map<String, String>

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

但是密钥只能来自已注册密钥,因此为已注册密钥定义了一个枚举:

enum class RegisteredKey {
    NONE, ZOOM
}

并首先构建 EnumMap<> 以强制执行密钥类型:

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

doLog(enumParamMap)

问题一,有直接用数据构建enumMap的构造函数吗?

然后需要将 EnumMap 转换为 Map<>,以便 api.log() 接受它

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

问题2:有没有更简单的方法将enumMap映射到regular map?

像这样的东西应该可以用于初始化:

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

要获得法线贴图,只需调用 .toMutableMap():

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

我不确定我是否正确解释了你的第一个问题,但如果你的意思是你想初始化一个详尽的 EnumMap,其中每个键都有一个条目,类似于采用 lambda 的 Array 构造函数,你可以写像这样的:

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;
}

用法:

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

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

根据您的评论进行编辑:您可以像这样用 EnumMap 构造函数包装一个 mapOf 调用来做到这一点,但它会实例化一个中间一次性 LinkedHashMap :

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

相反,您可以编写如下辅助函数:

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

用法:

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

------

对于你的下一个问题,我不确定这是否真的更简单,但你可以这样做:

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

它更简洁,但是您分配的是一个列表和一些您不会按照自己的方式分配的对。