kotlin - 从 Kotlin 中的值列表创建 EnumMap

标签 kotlin kotlin-extension enum-map

我想定义 enum class 的扩展它接受与枚举常量顺序相同的值列表并输出 EnumMap .

我能做的是创建和扩展 List<V>具有来自 Enum<K>.values() 的键数组的对象作为输入。

好像难度是enum class本身不是具有 .values() 的对象方法。所以也许我的要求不明智。

这是一个使用列表扩展方法的工作示例。

import java.util.*

enum class Shoes(
    val title: String,
    val weight: Double) {
    WORKBOOT("tough", 11.0),
    SNEAKER("fast", 6.0),
    SLIPPER("soft", 3.0);
}

fun main(args: Array<String>) {
    val prices= listOf(11.5,8.2,3.5)
    val map = prices.enumMapOf(Shoes.values())
    map.print()
}

inline fun <reified K : Enum<K>, V> List<V>.enumMapOf(keys:Array<K>): EnumMap<K, V> {
    val map = EnumMap<K, V>(K::class.java)
    keys.forEachIndexed{i,k-> map[k]=this[i]}
    return map
}

fun <K:Enum<K>,V> EnumMap<K,V>.print() {
    this.forEach{k,v-> println("%d: %s --> %.2f".format(k.ordinal,k.name,v)) }
}

最佳答案

我认为您缺少的主要是 enumValues可以为您提供通用枚举值的方法。

这将允许您这样做(我也重新安排了创建 EnumMap 的代码,如果这看起来太复杂了,您可以坚持自己的解决方案):

inline fun <reified K : Enum<K>, V> Enum<K>.mappedTo(values: List<V>): EnumMap<K, V> {
    return enumValues<K>().zip(values).toMap(EnumMap(K::class.java))
}

当然,现在这个问题是调用语法 - 这个函数必须像这样调用,在枚举的实例上:

Shoes.WORKBOOT.mappedTo(listOf(11.5, 8.2, 3.5))

这没有多大意义。打这个电话会更好:

Shoes.mappedTo(listOf(11.5, 8.2, 3.5))

但据我所知,没有办法实现这种语法,因为你不能向通用枚举的伴生对象添加扩展,然后期望在特定枚举的伴生对象上调用它——那些不'就这样相互继承。

因此,也许您可​​以使用常规函数而不是创建扩展,并从通用参数而不是接收者获取枚举类型:

inline fun <reified K : Enum<K>, V> mapEnumTo(values: List<V>): EnumMap<K, V> {
    return enumValues<K>().zip(values).toMap(EnumMap(K::class.java))
}

mapEnumTo<Shoes, Double>(listOf(11.5, 8.2, 3.5))

您也必须在此处指定键的类型,因为您不能先有一个显式的泛型类型参数,然后再有一个隐式的泛型类型参数。但我认为这是非常好的语法,因为您会看到正在创建的映射的键和值类型。

关于kotlin - 从 Kotlin 中的值列表创建 EnumMap,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50975057/

相关文章:

generics - Kotlin 中泛型类的扩展函数

kotlin - kotlin 扩展属性的惰性初始化器中的这个引用

java - 为什么 EnumMap 为空值分配一个 Object 类对象?

java - 将原始值存储在 EnumMap 中

kotlin - 仅当变量为空时才分配变量

android - MessagingStyle 不显示文本

Kotlin 同步内联

Kotlin 有 array.indexOf 但我无法弄清楚如何做 array.indexOfBy { lambda }

android - 数据绑定(bind)表达式中的调用扩展