Scala 3新enum是否有对应Java EnumSet/EnumMap的等价实现?
Scala 3 原生枚举对应 EnumSet/EnumMap 的惯用实现方案
针对你定义的Scala 3枚举:
enum Translation(val bit: Byte): case FlipX extends Translation(1) case FlipY extends Translation(2) case RotateClockwise extends Translation(4) //90 degrees
以下是符合Scala 3惯用风格、性能接近Java EnumSet/EnumMap的实现方案,完全基于Scala标准库,排除Scala 2风格方案及Enumeratum库:
等价于 Java EnumSet 的实现
Java EnumSet 底层用位向量实现,Scala中可以用**BitSet**(不可变/可变)直接对应,结合你的枚举自带的bit值,既能保证内存效率,又能实现位运算级别的操作。
不可变版本(对应 ImmutableEnumSet)
import scala.collection.immutable.BitSet object Translation { // 定义专属的不可变集合类型 type EnumSet = BitSet val EmptyEnumSet: EnumSet = BitSet.empty // 快速构造枚举集合 def enumSet(elems: Translation*): EnumSet = BitSet.fromSpecific(elems.map(_.bit.toInt)) // 扩展BitSet方法,方便转回Translation实例集合 extension (set: EnumSet) def toTranslations: Set[Translation] = values.filter(t => set.contains(t.bit.toInt)).toSet } // 使用示例 val flipSet = Translation.enumSet(Translation.FlipX, Translation.FlipY) println(flipSet.toTranslations) // 输出 Set(FlipX, FlipY)
可变版本(对应 EnumSet)
如果需要修改集合,使用mutable.BitSet:
import scala.collection.mutable object TranslationMutable { type EnumSet = mutable.BitSet val EmptyEnumSet: EnumSet = mutable.BitSet.empty def enumSet(elems: Translation*): EnumSet = { val set = mutable.BitSet.empty elems.foreach(t => set.add(t.bit.toInt)) set } extension (set: EnumSet) def toTranslations: mutable.Set[Translation] = mutable.Set.from(Translation.values.filter(t => set.contains(t.bit.toInt))) } // 使用示例 val mutableSet = TranslationMutable.enumSet(Translation.RotateClockwise) mutableSet.add(Translation.FlipX.bit.toInt) println(mutableSet.toTranslations) // 输出 Set(RotateClockwise, FlipX)
如果不需要极致的位运算性能,直接用Scala标准库的Set[Translation](不可变)或mutable.Set[Translation]也完全符合Scala惯用风格,性能对于大多数场景足够。
等价于 Java EnumMap 的实现
Java EnumMap 针对枚举键做了哈希优化,Scala标准库的**Map[Translation, V](不可变)和mutable.Map[Translation, V]**(可变)已经对枚举类型的键做了类似优化——因为枚举实例是单例,哈希值稳定且冲突概率极低,性能与EnumMap相当。
不可变版本(对应 ImmutableEnumMap)
// 直接构造不可变枚举映射 val immutableTranslationMap: Map[Translation, String] = Map( Translation.FlipX -> "水平翻转", Translation.FlipY -> "垂直翻转", Translation.RotateClockwise -> "顺时针旋转90度" ) // 取值示例 println(immutableTranslationMap(Translation.FlipX)) // 输出 水平翻转
可变版本(对应 EnumMap)
import scala.collection.mutable // 构造可变枚举映射 val mutableTranslationMap: mutable.Map[Translation, String] = mutable.Map.empty // 添加/修改元素 mutableTranslationMap(Translation.FlipX) = "水平翻转" mutableTranslationMap.update(Translation.RotateClockwise, "顺时针旋转90度") // 取值示例 println(mutableTranslationMap(Translation.RotateClockwise)) // 输出 顺时针旋转90度
如果需要更极致的性能,也可以使用mutable.OpenHashMap[Translation, V],它的底层实现更接近Java EnumMap的数组存储方式,对于枚举键的访问速度更快。
内容的提问来源于stack exchange,提问作者chaotic3quilibrium
相关产品推荐
相关产品推荐

