【问题标题】:Initialize an EnumMap from all of enum's values从所有枚举值初始化一个 EnumMap
【发布时间】:2021-11-25 21:38:51
【问题描述】:

我有一个枚举类:

enum class E { A, B, C, D }

初始化包含 E 的所有值作为键的 EnumMap 的最简洁方法是什么,每个键的初始值都为 0?

val map = ...?
assert(map is EnumMap<E, Int>)
assert(map[E.A] == 0)
assert(map[E.B] == 0)
assert(map[E.C] == 0)
assert(map[E.D] == 0)

我能想到的最简洁的是:

val map = E.values().associateWithTo(EnumMap(E::class.java)) { 0 }

但是,E 名称的重复违反了 DRY 原则。而associateWithTo这个词有点拗口。有没有更简洁易读的方式?我希望有像 EnumMap.allOf() 这样的东西,就像有 EnumSet.allOf() 一样。

【问题讨论】:

  • 你真的需要EnumMap吗? Map 还不够吗?
  • 这张地图每秒会被使用数十万次。 enumMap 将等效于数组索引。其他映射效率较低:hashmap 会查找枚举值的哈希码并转到包含链表的表。

标签: kotlin enum-map


【解决方案1】:

我能想到的最简单的方法是:

val map = EnumMap(E.values().associateWith { 0 })

【讨论】:

  • 是的,我认为这是最基本的,没有重复,也不需要明确指定类型。如果你愿意,你可以像 E.values().associateWith { 0 }.run(::EnumMap) 这样链接它。如果这是你的事,你可以使用enumValues&lt;E&gt;(),就像@broot 在效用函数理念中所做的那样。但是你需要一个吗?如果您经常这样做,那么也许可以,但我认为这非常简单易读!
  • 感谢@cactustictacs 的提示。我也更喜欢它,因为它看起来更具可读性,但我想说我们正在进入个人喜好领域;)
  • 哦,那些 cmets 的目标是 OP,而不是你!因为他们正在寻找可能性和所有
  • 是的,我明白了。尽管如此,它们也很好地提示了我其他可能的方法。对同一个问题有不同的观点总是好的;)
  • 哦,对了,不用担心!是的,我喜欢指出链接的东西,因为我认为功能性管道方法有时更具可读性。尽管这个很短,但很高兴能够从左到右阅读它为E -&gt; get its values -&gt; make a map with each one set to 0 -&gt; turn that into an EnumMap。这里不一定更好,但就像你说的,个人喜好!
【解决方案2】:

您始终可以为此创建自己的实用程序函数:

fun main() {
    val map = enumMap<E, Int> { 0 }
}

inline fun <reified E : Enum<E>, V> enumMap(valueSelector: (E) -> V): EnumMap<E, V> {
    return enumValues<E>().associateWithTo(EnumMap(E::class.java), valueSelector)
}

【讨论】:

    【解决方案3】:
    val map = EnumMap(EnumSet.allOf(E::class.java).associateWith { 0 })
    // {A=0, B=0, C=0, D=0}
    

    或者,如果您想要带有“序数”(枚举中的位置)的地图:

    val map = EnumMap(EnumSet.allOf(E::class.java).associateWith(E::ordinal))
    // {A=0, B=1, C=2, D=3}
    

    这将是具有自定义属性的枚举版本:

    enum class E(val value: String) {
      A("AAA"),
      B("BBB"),
      C("CCC"),
      D("DDD")
    }
    
    val map = EnumMap(EnumSet.allOf(E::class.java).associateWith(E::value))
    // {A=AAA, B=BBB, C=CCC, D=DDD}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-01
      • 1970-01-01
      相关资源
      最近更新 更多