kotlin, как конвертировать EnumMap в обычную карту - PullRequest
0 голосов
/ 09 октября 2019

нужно вызвать 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)

вопрос 1, есть ли конструктор для построения 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 с обычной картой?

Ответы [ 2 ]

2 голосов
/ 09 октября 2019

Я не уверен, что правильно интерпретирую ваш первый вопрос, но если вы хотите сказать, что хотите инициализировать исчерпывающую таблицу EnumMap, в которой каждый ключ имеет запись, аналогично конструктору Array, который принимает лямбду, вы можете написать такой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;
}

Использование:

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

или

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

Редактировать на основе вашего комментария: Вы можете сделать это, обернувmapOf вызов с конструктором EnumMap, подобным этому, но это будет создание экземпляра промежуточного одноразового использования 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())

Это более кратко, но вы распределяете список и несколько пар, которые вам не подойдут.

1 голос
/ 09 октября 2019

Примерно так должно работать для инициализации:

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