以下内容来自EnumMap的Java文档的实现说明部分:
实现说明:所有基本操作都在恒定时间内执行。 他们可能(尽管不能保证)比他们的更快 哈希图对应物。
我也在 java 文档中看到了类似的行EnumSet
.我想知道为什么EnumSets
和EnumMaps
更有可能比散列的对应物更快?
EnumSet
由位数组支持。由于您可以放入EnumSet
的不同项目的数量是事先知道的,因此我们可以简单地为每个枚举值保留一位。您可以想象对Set<Byte>
或Set<Short>
进行类似的优化,但对于Set<Integer>
(2^32 位需要 0.5 GiB 的内存)或一般情况下是不可行的。
因此,像exists
或add
等基本操作是恒定时间(就像HashSet
一样),但它们只需要检查或设置一位。没有hashCode()
计算。这就是为什么EnumSet
更快。还有更复杂的操作,如联合或使用位操作技术轻松实现。
在OpenJDK中,EnumSet
有两种实现:RegularEnumSet
能够处理long
中最多64个值的枚举,JumboEnumSet
处理更大的枚举(使用long[]
)。但这只是一个实现细节。
EnumMap
的工作原理类似,但它使用 Object[]
来存储值,而键(索引)是从 Enum.ordinal()
隐式推断出来的。
>EnumSet
内部使用array[]和自然顺序,并随之而来:
-
fast:get/set 由常量时间 O(1) 调用,
hashCode()
不用于查找正确的存储桶 - 内存效率:数组的大小由枚举大小预定义,不是动态的
EnumMap
使用枚举作为密钥,基于与无法进行哈希代码冲突的EnumSet
相同的主体