精通 Java EnumMap:高效枚举键值映射实战
Java EnumMap
本教程通过示例讲解 Java EnumMap 类及其操作。
Java 集合框架中的 EnumMap 类为枚举元素提供 Map 实现。
在 EnumMap 中,枚举元素作为 键 使用。它实现 Map 接口。

学习 EnumMap 前,请确保了解 Java 枚举。
创建 EnumMap
创建枚举映射前,需先导入 java.util.EnumMap 包。导入后,可按如下方式创建:
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
EnumMap<Size, Integer> sizes = new EnumMap<>(Size.class);
上例创建了名为 sizes 的枚举映射。
其中:
- Size — 枚举的 键,映射到值
- Integer — 枚举映射中与对应键关联的 值
EnumMap 的方法
EnumMap 类提供多种方法操作枚举映射。
向 EnumMap 插入元素
put()— 插入指定键值映射(条目)。putAll()— 插入指定 Map 的所有条目。
示例:
import java.util.EnumMap;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
// 创建 Size 枚举的 EnumMap
EnumMap<Size, Integer> sizes1 = new EnumMap<>(Size.class);
// 使用 put() 方法
sizes1.put(Size.SMALL, 28);
sizes1.put(Size.MEDIUM, 32);
System.out.println("EnumMap1: " + sizes1);
EnumMap<Size, Integer> sizes2 = new EnumMap<>(Size.class);
// 使用 putAll() 方法
sizes2.putAll(sizes1);
sizes2.put(Size.LARGE, 36);
System.out.println("EnumMap2: " + sizes2);
}
}
输出
EnumMap1: {SMALL=28, MEDIUM=32}
EnumMap2: {SMALL=28, MEDIUM=32, LARGE=36}
上例使用 putAll() 将 sizes1 的所有元素插入 sizes2。
也可用 putAll() 从 HashMap、TreeMap 等其他 Map 向枚举映射插入元素,但所有 Map 必须为同一枚举类型。
访问 EnumMap 元素
1. 使用 entrySet()、keySet() 和 values()
entrySet()— 返回枚举映射所有键值映射(条目)的集合。keySet()— 返回枚举映射所有键的集合。values()— 返回枚举映射所有值的集合。
示例:
import java.util.EnumMap;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
// 创建 Size 枚举的 EnumMap
EnumMap<Size, Integer> sizes = new EnumMap<>(Size.class);
sizes.put(Size.SMALL, 28);
sizes.put(Size.MEDIUM, 32);
sizes.put(Size.LARGE, 36);
sizes.put(Size.EXTRALARGE, 40);
System.out.println("EnumMap: " + sizes);
// 使用 entrySet()
System.out.println("键值映射: " + sizes.entrySet());
// 使用 keySet()
System.out.println("Keys: " + sizes.keySet());
// 使用 values()
System.out.println("Values: " + sizes.values());
}
}
输出
EnumMap: {SMALL=28, MEDIUM=32, LARGE=36, EXTRALARGE=40}
键值映射: [SMALL=28, MEDIUM=32, LARGE=36, EXTRALARGE=40]
Keys: [SMALL, MEDIUM, LARGE, EXTRALARGE]
Values: [28, 32, 36, 40]
2. 使用 get() 方法
get() 返回指定键关联的值,键不存在返回 null。
示例:
import java.util.EnumMap;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumMap<Size, Integer> sizes = new EnumMap<>(Size.class);
sizes.put(Size.SMALL, 28);
sizes.put(Size.MEDIUM, 32);
sizes.put(Size.LARGE, 36);
sizes.put(Size.EXTRALARGE, 40);
System.out.println("EnumMap: " + sizes);
// 使用 get()
int value = sizes.get(Size.MEDIUM);
System.out.println("MEDIUM 的值: " + value);
}
}
输出
EnumMap: {SMALL=28, MEDIUM=32, LARGE=36, EXTRALARGE=40}
MEDIUM 的值: 32
移除 EnumMap 元素
remove(key)— 返回并移除指定键关联的条目。remove(key, value)— 仅当指定键映射到指定值时移除条目,返回布尔值。
示例:
import java.util.EnumMap;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumMap<Size, Integer> sizes = new EnumMap<>(Size.class);
sizes.put(Size.SMALL, 28);
sizes.put(Size.MEDIUM, 32);
sizes.put(Size.LARGE, 36);
sizes.put(Size.EXTRALARGE, 40);
System.out.println("EnumMap: " + sizes);
// 使用 remove()
int value = sizes.remove(Size.MEDIUM);
System.out.println("移除的值: " + value);
boolean result = sizes.remove(Size.SMALL, 28);
System.out.println("条目 {SMALL=28} 是否移除? " + result);
System.out.println("更新后的 EnumMap: " + sizes);
}
}
输出
EnumMap: {SMALL=28, MEDIUM=32, LARGE=36, EXTRALARGE=40}
移除的值: 32
条目 {SMALL=28} 是否移除? true
更新后的 EnumMap: {LARGE=36, EXTRALARGE=40}
替换 EnumMap 元素
replace(key, value)— 用新 value 替换指定 key 关联的值。replace(key, old, new)— 仅当 old 值已关联到指定 key 时,用 new 替换 old。replaceAll(function)— 用指定 function 的结果替换映射中每个值。
import java.util.EnumMap;
class Main {
enum Size { SMALL, MEDIUM, LARGE, EXTRALARGE }
public static void main(String[] args) {
EnumMap<Size, Integer> sizes = new EnumMap<>(Size.class);
sizes.put(Size.SMALL, 28);
sizes.put(Size.MEDIUM, 32);
sizes.put(Size.LARGE, 36);
sizes.put(Size.EXTRALARGE, 40);
System.out.println("EnumMap: " + sizes);
// 使用 replace()
sizes.replace(Size.MEDIUM, 30);
sizes.replace(Size.LARGE, 36, 34);
System.out.println("replace() 后的 EnumMap: " + sizes);
// 使用 replaceAll()
sizes.replaceAll((key, oldValue) -> oldValue + 3);
System.out.println("replaceAll() 后的 EnumMap: " + sizes);
}
}
输出
EnumMap: {SMALL=28, MEDIUM=32, LARGE=36, EXTRALARGE=40}
replace() 后的 EnumMap: {SMALL=28, MEDIUM=30, LARGE=34, EXTRALARGE=40}
replaceAll() 后的 EnumMap: {SMALL=31, MEDIUM=33, LARGE=37, EXTRALARGE=43}
注意上述语句:
sizes.replaceAll((key, oldValue) -> oldValue + 3);
该方法访问映射所有条目,并用 lambda 表达式提供的新值替换所有值。
其他方法
| 方法 | 说明 |
|---|---|
clone() | 创建 EnumMap 副本 |
containsKey() | 搜索指定键,返回布尔结果 |
containsValue() | 搜索指定值,返回布尔结果 |
size() | 返回 EnumMap 大小 |
clear() | 移除所有条目 |
EnumSet 与 EnumMap 对比
EnumSet 和 EnumMap 均提供存储枚举值的数据结构,但存在主要差异:
- EnumSet 内部以位序列表示;EnumMap 内部以数组表示。
- EnumSet 通过预定义方法创建(如
allOf()、noneOf()、of()等);EnumMap 通过构造器创建。
Cloneable 与 Serializable 接口
EnumMap 类还实现了 Cloneable 和 Serializable 接口。
Cloneable 接口
允许 EnumMap 类复制其实例。
Serializable 接口
Java 对象网络传输需转为位或字节,因对象无法直接传输。Serializable 接口允许类被序列化,即实现该接口的类的对象可转为位或字节。
java