EnumSet和EnumMap专为枚举设计,利用位向量和数组索引实现高效存储与访问,相比HashSet和HashMap避免了哈希开销,提升性能与内存效率,适用于权限、状态、配置等场景。

Java里,当我们处理枚举类型(Enum)的集合或映射时,
EnumSet
EnumMap
Set
Map
HashSet<MyEnum>
HashMap<MyEnum, SomeValue>
EnumSet
EnumMap
EnumSet:枚举的集合,高效且安全
想象一下,你需要表示一个用户拥有哪些权限,而这些权限都是枚举类型,比如
Permission.READ
Permission.WRITE
Permission.READ_WRITE
HashSet<Permission>
EnumSet
立即学习“Java免费学习笔记(深入)”;
它是一个抽象类,提供了几种静态工厂方法来创建具体实例,比如
EnumSet.noneOf(Permission.class)
EnumSet.allOf(Permission.class)
EnumSet.of(Permission.READ, Permission.WRITE)
EnumSet
EnumSet
long
public enum Permission {
READ, WRITE, DELETE, EXECUTE, ADMIN
}
// 示例:用户权限管理
public class UserPermissions {
private EnumSet<Permission> permissions;
public UserPermissions(EnumSet<Permission> initialPermissions) {
this.permissions = initialPermissions;
}
public void addPermission(Permission p) {
permissions.add(p);
System.out.println("Added " + p + ". Current permissions: " + permissions);
}
public void removePermission(Permission p) {
permissions.remove(p);
System.out.println("Removed " + p + ". Current permissions: " + permissions);
}
public boolean hasPermission(Permission p) {
return permissions.contains(p);
}
public static void main(String[] args) {
EnumSet<Permission> defaultPermissions = EnumSet.of(Permission.READ, Permission.WRITE);
UserPermissions user = new UserPermissions(defaultPermissions);
System.out.println("Initial permissions: " + user.permissions); // Output: [READ, WRITE]
user.addPermission(Permission.DELETE); // Output: Added DELETE. Current permissions: [READ, WRITE, DELETE]
System.out.println("Has EXECUTE permission? " + user.hasPermission(Permission.EXECUTE)); // Output: false
user.removePermission(Permission.WRITE); // Output: Removed WRITE. Current permissions: [READ, DELETE]
EnumSet<Permission> allAdminPermissions = EnumSet.allOf(Permission.class);
System.out.println("All admin permissions: " + allAdminPermissions); // Output: [READ, WRITE, DELETE, EXECUTE, ADMIN]
}
}EnumMap:枚举键的映射,性能卓越
与
EnumSet
EnumMap
EnumMap
HashMap<MyEnum, SomeValue>
EnumMap
ordinal()
EnumMap
ordinal()
public enum TrafficLight {
RED("Stop"),
YELLOW("Prepare to stop"),
GREEN("Go");
private final String description;
TrafficLight(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
// 示例:交通灯状态管理
public class TrafficLightSystem {
private EnumMap<TrafficLight, Integer> durationMap; // 存储每个灯亮的时长
public TrafficLightSystem() {
durationMap = new EnumMap<>(TrafficLight.class);
durationMap.put(TrafficLight.RED, 60);
durationMap.put(TrafficLight.YELLOW, 5);
durationMap.put(TrafficLight.GREEN, 45);
}
public int getDuration(TrafficLight light) {
return durationMap.get(light);
}
public void updateDuration(TrafficLight light, int newDuration) {
durationMap.put(light, newDuration);
System.out.println("Updated " + light + " duration to " + newDuration + " seconds.");
}
public static void main(String[] args) {
TrafficLightSystem system = new TrafficLightSystem();
System.out.println("Red light duration: " + system.getDuration(TrafficLight.RED) + " seconds."); // Output: 60 seconds.
system.updateDuration(TrafficLight.YELLOW, 7); // Output: Updated YELLOW duration to 7 seconds.
System.out.println("Yellow light new duration: " + system.getDuration(TrafficLight.YELLOW) + " seconds."); // Output: 7 seconds.
// 遍历EnumMap
for (EnumMap.Entry<TrafficLight, Integer> entry : system.durationMap.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue() + " seconds (" + entry.getKey().getDescription() + ")");
}
}
}简单来说,当你的集合或映射的“关键”是枚举时,
EnumSet
EnumMap
这个问题,其实是很多Java开发者在初次接触
EnumSet
HashSet<Enum>
HashSet
hashCode()
Node
而
EnumSet
Set
EnumSet
如果你的枚举类型常量数量不超过64个(这是因为一个
long
EnumSet
long
例如,
Permission.READ
ordinal()
Permission.WRITE
READ
WRITE
EnumSet
long
0b...0011
add(Permission.DELETE)
DELETE
remove(Permission.WRITE)
WRITE
contains(Permission.READ)
READ
这些位操作都是CPU指令级别的,效率极高,是真正的O(1)常数时间。
如果枚举常量的数量超过64个,
EnumSet
JumboEnumSet
long[]
long
HashSet
所以,总结一下,
EnumSet
long
这就像是,
HashSet
EnumSet
EnumMap
EnumSet
HashMap
HashMap<Enum, V>
HashSet
put
get
HashMap
Entry
而
EnumMap
Object[]
EnumMap
EnumMap
ordinal()
当你要
put(key, value)
EnumMap
key.ordinal()
value
key.ordinal()
get(key)
key.ordinal()
key.ordinal()
// 内部简化示意,实际代码会更复杂,有边界检查和类型转换
// private final Object[] vals;
// vals = new Object[keyType.getEnumConstants().length];
// public V put(K key, V value) {
// vals[key.ordinal()] = value;
// return null; // 简化
// }
// public V get(Object key) {
// return (V) vals[((Enum<?>)key).ordinal()];
// }这种基于数组索引的访问,效率是极高的,是纯粹的O(1)操作,比哈希表的平均O(1)还要快,因为它根本不需要计算哈希码,也不存在哈希冲突。内存开销也更小,因为它不需要为每个键值对创建额外的
Entry
所以,
EnumMap
在我看来,
EnumMap
在日常的Java项目开发中,
EnumSet
EnumMap
何时优先考虑:
处理枚举集合时(EnumSet):
READ
WRITE
DELETE
EnumSet
ACTIVE
PAUSED
LOCKED
EnumSet
EnumSet
EnumSet
处理枚举键值映射时(EnumMap):
TrafficLight.RED
60
TrafficLight.YELLOW
5
EnumMap
Operation.ADD
AdditionStrategy
Operation.SUBTRACT
SubtractionStrategy
EnumMap
EnumMap
EnumMap<MyEnum, Integer>
常见误区:
EnumSet
EnumMap
Collections.synchronizedSet
Collections.synchronizedMap
ConcurrentHashMap
EnumMap
EnumSet
EnumMap
EnumSet.allOf()
EnumSet.allOf(MyEnum.class)
EnumSet.noneOf(MyEnum.class)
EnumMap
Enum
// 错误或不推荐:这样写,虽然能编译,但失去了EnumMap的类型安全和部分优化 // EnumMap<Enum, String> map = new EnumMap<>(MyEnum.class); // 应该这样写: EnumMap<MyEnum, String> map = new EnumMap<>(MyEnum.class);
EnumMap
Class<K>
Enum
EnumMap
HashSet
HashMap
EnumSet
EnumMap
在我看来,
EnumSet
EnumMap
EnumSet
EnumMap
以上就是EnumSet和EnumMap在Java中的应用的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号