网站首页 > 精选教程 正文
EnumMap 的用法
EnumMap 在使用上跟 HashMap 差不多,但是 EnumMap 的性能更好,所以,如果键为 Enum 类型时,建议使用 EnumMap 代替 HashMap。
public enum Color {
YELLOW, RED, BLUE, BLACK
}
public static void main(String[] args) {
EnumMap<Color, Integer> colorMap = new EnumMap<>(Color.class);
for (Color value : Color.values()) {
colorMap.put(value, value.ordinal());
}
colorMap.forEach((k, v) -> System.out.println(k + " -> " + v));
}
输出结果如下
YELLOW -> 0
RED -> 1
BLUE -> 2
BLACK -> 3
使用上没什么可说的,关键从源码讲一下 EnumMap 为什么在性能上会更好。
看一下 EnumMap 的结构定义
- keyType:记录枚举数据类型
- keyUniverse:存储所有的枚举实例,
- vals:存储值,与 keyUniverse 数组等长,存储的值与 keyUniverse 的索引对应
public class EnumMap<K extends Enum<K>, V>
extends AbstractMap<K, V> implements Serializable, Cloneable {
private final Class<K> keyType;
private transient K[] keyUniverse;
private transient Object[] vals;
private transient int size = 0;
}
EnumMap 在初始化时就会将枚举的所有实例存储到 keyUniverse 数组,vals 则初始化为与 keyUniverse 等长的数组,每个元素填充为 null。
新增数据时,获取枚举实例的 ordinal 作为索引,然后直接赋值到 vals 相应的索引即可,时间复杂度为 O1。
public V put(K var1, V var2) {
this.typeCheck(var1);
int var3 = var1.ordinal();
Object var4 = this.vals[var3];
this.vals[var3] = this.maskNull(var2);
if (var4 == null) {
++this.size;
}
return this.unmaskNull(var4);
}
获取数据时,获取枚举实例的 ordinal 作为索引,直接从 vals 数组获取相应索引位置的值即可,时间复杂度为 O1。
public V get(Object var1) {
return this.isValidKey(var1) ? this.unmaskNull(this.vals[((Enum)var1).ordinal()]) : null;
}
EnumMap 之所以可以这么操作,是因为枚举的实例是有限的,而每个实例通过 ordinal() 方法可以确定其索引位置,这样 Map 的操作就转化成了对 vals 数组的操作,所以效率非常高。
EnumSet 的用法
创建空集合
EnumSet.noneOf(Color.class);
创建包含所有元素的集合
EnumSet.allOf(Color.class);
创建包含指定元素的集合
EnumSet.of(Color.YELLOW, Color.RED);
创建范围集合
第一个枚举值的索引位置必须大于第二个枚举值,不然会导致异常。
public static void main(String[] args) {
EnumSet<Color> rangeColorSet = EnumSet.range(Color.YELLOW, Color.BLUE);
// 输出 [YELLOW, RED, BLUE]
System.out.println(rangeColorSet);
}
补集
public static void main(String[] args) {
EnumSet<Color> partColorSet = EnumSet.of(Color.YELLOW, Color.RED);
EnumSet<Color> remainderColorSet = EnumSet.complementOf(partColorSet);
// 输出 [BLUE, BLACK]
System.out.println(remainderColorSet);
}
复制创建集合
public static void main(String[] args) {
List<Color> colorList = new ArrayList<>();
Collections.addAll(colorList, Color.YELLOW, Color.RED, Color.RED);
// 输出 [YELLOW, RED, RED]
System.out.println(colorList);
EnumSet<Color> colorSet = EnumSet.copyOf(colorList);
// 输出 [YELLOW, RED]
System.out.println(colorSet);
}
写在最后:关注我,学习更多JAVA性能优化的技巧
- 上一篇: 枚举虽好,但务必记得避坑
- 下一篇: Delphi基础教程图文版之数据类型(枚举)
猜你喜欢
- 2025-01-10 如何使用JavaScript遍历对象?
- 2025-01-10 面试官:来,讲一下枚举类型在开发时中实际应用场景!
- 2025-01-10 SpringBoot中Jackson实现自定义序列化和反序列化控制5种方式总结
- 2025-01-10 Delphi基础教程图文版之数据类型(枚举)
- 2025-01-10 枚举虽好,但务必记得避坑
- 2025-01-10 Python学习 -- 枚举类
- 2025-01-10 为什么阿里不建议在返回对象中使用枚举
- 2025-01-10 你知道 Java 中关键字 enum 是一个语法糖吗?反编译枚举类
- 2025-01-10 深入剖析枚举:从简单概念到高级应用
- 2025-01-10 Java 枚举与策略模式、函数式接口的结合:实现高内聚低耦合的设计
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)