EnumMap:让Java Map更高效的技巧
EnumMap。这玩意儿是我在开发过程中偶然发现的,简直就像是Java中隐藏的一颗宝藏。Map来做一些基于枚举类型的映射,估计这个工具会让你事半功倍,不信?那就往下看吧!EnumMap。很多时候,我们在写代码时会遇到这种需求:需要用Map来存储枚举值和对应的对象或数据。HashMap<EnumType, Object>来做这个映射。但是,这种方式在性能上并不总是最优,尤其是在枚举类型比较少的时候。EnumMap。# 什么是EnumMap?
EnumMap是Java Collections框架中的一个特例化的Map实现。顾名思义,它是专门用于枚举类型作为键的Map。它比HashMap在处理枚举键时要高效得多,原因是什么呢?我们可以通过下面的几个角度来理解:内存优化: EnumMap内部并不像HashMap那样使用哈希桶,它直接使用了枚举值的序号。这意味着在内存分配上,EnumMap会比HashMap更加高效,因为它不需要额外的空间来存储哈希码。速度提升:由于它是根据枚举值的序号来存储数据,查找操作几乎是常数时间复杂度(O(1)),而不像 HashMap那样需要计算哈希值,减少了性能开销。类型安全: EnumMap要求键必须是枚举类型,这就避免了错误地使用不合适的键类型,增强了类型安全。
# 如何使用EnumMap?
EnumMap之前,首先你得了解一个条件:它只支持枚举类型的键。你不能在EnumMap中存储其他类型的对象,像String或者Integer这样的类型都不行。基本的创建方式
EnumMap其实非常简单:import java.util.EnumMap;public class EnumMapExample {
// 定义一个枚举类型
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}public static void main(String[] args) {
// 创建一个EnumMap,键为Day枚举类型,值为String
EnumMap<Day, String> enumMap = new EnumMap<>(Day.class);// 插入一些值
enumMap.put(Day.MONDAY, "Start of the week");
enumMap.put(Day.WEDNESDAY, "Midweek");
enumMap.put(Day.FRIDAY, "Almost weekend");// 打印
System.out.println(enumMap);
}
}
{MONDAY=Start of the week, WEDNESDAY=Midweek, FRIDAY=Almost weekend}
Map,而且直接指定了枚举类型作为键。EnumMap的构造函数接受枚举类型的Class对象作为参数,所以它是类型安全的。EnumMap的实现原理
EnumMap的实现非常有意思。它并不像HashMap那样通过链表和哈希桶来存储数据,而是使用了一个简单的数组来存储对应的值。为什么这么做呢?原因很简单——枚举值本身就是固定的,数量非常有限,因此EnumMap通过枚举的ordinal()方法(即枚举值的序号)来直接索引到一个数组的位置,进行存取操作。内部存储
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
EnumMap会创建一个数组,长度等于枚举值的个数(在这个例子中是7)。数组的每个索引位置会对应枚举中的每一个值。存取元素时,EnumMap只需要通过Day.MONDAY.ordinal()来快速定位到数组中的位置。这个方法返回的是MONDAY在枚举中的位置(0),这样就可以通过数组的索引直接存取数据了。# EnumMap的例子
EnumMap的应用。Day枚举类型就可以作为Map的键,而每天的任务作为值。import java.util.EnumMap; public class TaskManager {
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}public static void main(String[] args) {
// 创建一个EnumMap,键为Day,值为String
EnumMap<Day, String> taskMap = new EnumMap<>(Day.class);// 填充任务
taskMap.put(Day.MONDAY, "Meeting with team");
taskMap.put(Day.TUESDAY, "Code review");
taskMap.put(Day.WEDNESDAY, "Research new tech");
taskMap.put(Day.THURSDAY, "Write documentation");
taskMap.put(Day.FRIDAY, "Deploy updates");
taskMap.put(Day.SATURDAY, "Rest");
taskMap.put(Day.SUNDAY, "Plan for next week");// 打印周日程
taskMap.forEach((day, task) -> System.out.println(day + ": " + task));
}
}
MONDAY: Meeting with team
TUESDAY: Code review
WEDNESDAY: Research new tech
THURSDAY: Write documentation
FRIDAY: Deploy updates
SATURDAY: Rest
SUNDAY: Plan for next week
EnumMap不仅提供了非常高效的存取方式,而且在代码上也非常直观易懂。你只需知道一天的枚举类型,直接取出对应的任务就行了。测试用例
EnumMap真的是高效呢?我们来写个简单的性能对比测试,看看它和HashMap到底差距有多大。import java.util.HashMap;
import java.util.EnumMap;
import java.util.Map;public class PerformanceTest {
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}public static void main(String[] args) {
// 创建HashMap和EnumMap
Map<Day, String> hashMap = new HashMap<>();
Map<Day, String> enumMap = new EnumMap<>(Day.class);// 插入1000000个数据进行对比
long start = System.nanoTime();
for (int i = 0; i < 1000000; i++) {
hashMap.put(Day.MONDAY, "Task " + i);
}
long end = System.nanoTime();
System.out.println("HashMap插入耗时:" + (end - start) + "ns");start = System.nanoTime();
for (int i = 0; i < 1000000; i++) {
enumMap.put(Day.MONDAY, "Task " + i);
}
end = System.nanoTime();
System.out.println("EnumMap插入耗时:" + (end - start) + "ns");
}
}
EnumMap的速度要比HashMap快得多。尤其在枚举类型的键值较少时,EnumMap的优势更加明显。总结
EnumMap有了一个更深的了解。它不仅在性能上比HashMap更优,而且它的实现方式非常简单明了,适合用在需要频繁查找基于枚举类型映射的场景中。EnumMap了没?欢迎在评论区分享使用体验!-END-
ok,今天先说到这,老规矩,看完文章记得右下角给何老师点赞。
最后送给大家一个福利,我这里有一份搞副业的教程,这份教程里有100+个搞钱小项目:
网盘拉新核心玩法、公众号运营变现、小红书虚拟资料引流等,现在扫码加我微信,即可领取这份副业教程。
添加时备注:副业