Java EnumMap类
EnumMap是Map接口的一个专门实现,用于枚举类型。它扩展了AbstractMap并实现了Java中的Map接口。它属于java.util包。EnumMap的几个重要特征如下。
- EnumMap类是Java集合框架的一个成员,不具有同步性。
- EnumMap是一个有序的集合,它们按照键的自然顺序被维护(键的自然顺序是指枚举类型中枚举常量被声明的顺序)。
- 这是一个高性能的Map实现,比HashMap快很多。
- 每个EnumMap实例的所有键必须是单一枚举类型的键。
- EnumMap不允许空键,当我们试图插入空键时,会抛出NullPointerException 。
- 由集合视图返回的迭代器是弱一致性的:它们永远不会抛出ConcurrentModificationException,而且它们可能会也可能不会显示在迭代过程中发生的对Map的任何修改的效果。
- EnumMap内部表示为数组。这种表示方法是非常紧凑和高效的。
语法: 声明
public class EnumMap<K extends Enum<K>,V> extends AbstractMap<K,V> implements Serializable, Cloneable
参数
- 关键对象类型
- 值对象类型
K 必须扩展Enum,它强制要求键必须是指定的枚举类型。
EnumMap层次结构
EnumMap的构造函数
- EnumMap(Class keyType): 该构造函数用于创建一个具有指定 keyType 的空EnumMap 。
- EnumMap(EnumMap m): 该构造函数用于创建一个与指定的枚举Map具有相同keyType的枚举Map,初始映射与EnumMap相同。
- EnumMap(Map m): 构造函数用于创建一个枚举Map,初始化来自参数中指定的Map。
例子
// Java Program to illustrate Working of EnumMap class
// and its functions
// Importing EnumMap class
import java.util.EnumMap;
// Main class
public class EnumMapExample {
// Enum
public enum GFG {
CODE,
CONTRIBUTE,
QUIZ,
MCQ;
}
// Main driver method
public static void main(String args[])
{
// Java EnumMap
// Creating an empty EnumMap with key
// as enum type state
EnumMap<GFG, String> gfgMap
= new EnumMap<GFG, String>(GFG.class);
// Putting values inside EnumMap in Java
// Inserting Enum keys different from
// their natural order
gfgMap.put(GFG.CODE, "Start Coding with gfg");
gfgMap.put(GFG.CONTRIBUTE, "Contribute for others");
gfgMap.put(GFG.QUIZ, "Practice Quizes");
gfgMap.put(GFG.MCQ, "Test Speed with Mcqs");
// Printing size of EnumMap
System.out.println("Size of EnumMap in java: "
+ gfgMap.size());
// Printing Java EnumMap
// Print EnumMap in natural order
// of enum keys (order on which they are declared)
System.out.println("EnumMap: " + gfgMap);
// Retrieving value from EnumMap
System.out.println("Key : " + GFG.CODE + " Value: "
+ gfgMap.get(GFG.CODE));
// Checking if EnumMap contains a particular key
System.out.println(
"Does gfgMap has " + GFG.CONTRIBUTE + ": "
+ gfgMap.containsKey(GFG.CONTRIBUTE));
// Checking if EnumMap contains a particular value
System.out.println(
"Does gfgMap has :" + GFG.QUIZ + " : "
+ gfgMap.containsValue("Practice Quizes"));
System.out.println("Does gfgMap has :" + GFG.QUIZ
+ " : "
+ gfgMap.containsValue(null));
}
}
输出
Size of EnumMap in java: 4
EnumMap: {CODE=Start Coding with gfg, CONTRIBUTE=Contribute for others, QUIZ=Practice Quizes, MCQ=Test Speed with Mcqs}
Key : CODE Value: Start Coding with gfg
Does gfgMap has CONTRIBUTE: true
Does gfgMap has :QUIZ : true
Does gfgMap has :QUIZ : false
EnumMap的基本操作
操作1: 添加元素
为了向EnumMap添加元素,我们可以使用put()或putAll()方法,如下所示。
// Java Program to Add Elements to the EnumMap
// Importing EnumMap class
import java.util.EnumMap;
// Main class
// AddingElementsToEnumMap
class GFG {
enum Color { RED, GREEN, BLUE, WHITE }
public static void main(String[] args)
{
// Creating an EnumMap of the Color enum
EnumMap<Color, Integer> colors1
= new EnumMap<>(Color.class);
// Insert elements in Map
// using put() method
colors1.put(Color.RED, 1);
colors1.put(Color.GREEN, 2);
// Printing mappings to the console
System.out.println("EnumMap colors1: " + colors1);
// Creating an EnumMap of the Color Enum
EnumMap<Color, Integer> colors2
= new EnumMap<>(Color.class);
// Adding elements using the putAll() method
colors2.putAll(colors1);
colors2.put(Color.BLUE, 3);
// Printing mappings to the console
System.out.println("EnumMap colors2: " + colors2);
}
}
输出
EnumMap colors1: {RED=1, GREEN=2}
EnumMap colors2: {RED=1, GREEN=2, BLUE=3}
操作2: 访问元素
我们可以使用 entrySet(), keySet(), values(), get()来访问EnumMap的元素。下面的例子解释了这些方法。
// Java Program to Access the Elements of EnumMap
// Importing required classes
import java.util.EnumMap;
// Main class
// AccessElementsOfEnumMap
class GFG {
// Enum
enum Color { RED, GREEN, BLUE, WHITE }
// Main driver method
public static void main(String[] args)
{
// Creating an EnumMap of the Color enum
EnumMap<Color, Integer> colors
= new EnumMap<>(Color.class);
// Inserting elements using put() method
colors.put(Color.RED, 1);
colors.put(Color.GREEN, 2);
colors.put(Color.BLUE, 3);
colors.put(Color.WHITE, 4);
System.out.println("EnumMap colors : " + colors);
// Using the entrySet() method
System.out.println("Key/Value mappings: "
+ colors.entrySet());
// Using the keySet() method
System.out.println("Keys: " + colors.keySet());
// Using the values() method
System.out.println("Values: " + colors.values());
// Using the get() method
System.out.println("Value of RED : "
+ colors.get(Color.RED));
}
}
输出
EnumMap colors : {RED=1, GREEN=2, BLUE=3, WHITE=4}
Key/Value mappings: [RED=1, GREEN=2, BLUE=3, WHITE=4]
Keys: [RED, GREEN, BLUE, WHITE]
Values: [1, 2, 3, 4]
Value of RED : 1
操作3: 删除元素
为了删除元素,EnumMap提供了两种不同的remove()方法。
例子
// Java program to Remove Elements of EnumMap
// Importing EnumMap class
import java.util.EnumMap;
// Main class
class GFG {
// Enum
enum Color {
// Custom elements
RED,
GREEN,
BLUE,
WHITE
}
// Main driver method
public static void main(String[] args)
{
// Creating an EnumMap of the Color enum
EnumMap<Color, Integer> colors
= new EnumMap<>(Color.class);
// Inserting elements in the Map
// using put() method
colors.put(Color.RED, 1);
colors.put(Color.GREEN, 2);
colors.put(Color.BLUE, 3);
colors.put(Color.WHITE, 4);
// Printing colors in the EnumMap
System.out.println("EnumMap colors : " + colors);
// Removing a mapping
// using remove() Method
int value = colors.remove(Color.WHITE);
// Displaying the removed value
System.out.println("Removed Value: " + value);
// Removing specific color and storing boolean
// if removed or not
boolean result = colors.remove(Color.RED, 1);
// Printing the boolean result whether removed or
// not
System.out.println("Is the entry {RED=1} removed? "
+ result);
// Printing the updated Map to the console
System.out.println("Updated EnumMap: " + colors);
}
}
输出
EnumMap colors : {RED=1, GREEN=2, BLUE=3, WHITE=4}
Removed Value: 4
Is the entry {RED=1} removed? true
Updated EnumMap: {GREEN=2, BLUE=3}
操作4: 替换元素
Map接口提供了replace()方法的三种变化,以改变EnumMap的映射关系。
例子
// Java Program to Replace Elements of EnumMap
// Importing required classes
import java.util.EnumMap;
// Main class
class GFG {
// Enum
enum Color {
RED,
GREEN,
BLUE,
WHITE
}
// Main driver method
public static void main(String[] args)
{
// Creating an EnumMap of the Color enum
EnumMap<Color, Integer> colors
= new EnumMap<>(Color.class);
// Inserting elements to Map
// using put() method
colors.put(Color.RED, 1);
colors.put(Color.GREEN, 2);
colors.put(Color.BLUE, 3);
colors.put(Color.WHITE, 4);
// Printing all elements inside above Map
System.out.println("EnumMap colors " + colors);
// Replacing certain elements depicting colors
// using the replace() method
colors.replace(Color.RED, 11);
colors.replace(Color.GREEN, 2, 12);
// Printing the updated elements (colors)
System.out.println("EnumMap using replace(): "
+ colors);
// Replacing all colors using the replaceAll()
// method
colors.replaceAll((key, oldValue) -> oldValue + 3);
// Printing the elements of above Map
System.out.println("EnumMap using replaceAll(): "
+ colors);
}
}
输出
EnumMap colors {RED=1, GREEN=2, BLUE=3, WHITE=4}
EnumMap using replace(): {RED=11, GREEN=12, BLUE=3, WHITE=4}
EnumMap using replaceAll(): {RED=14, GREEN=15, BLUE=6, WHITE=7}
同步的EnumMap
EnumMap的实现是不同步的。这意味着,如果多个线程同时访问一个树形集合,并且至少有一个线程修改了该集合,就必须在外部进行同步。这通常是通过使用集合类的synchronizedMap()方法来完成的。这最好在创建时完成,以防止意外的非同步访问。
Map<EnumKey, V> m = Collections.synchronizedMap(new EnumMap<EnumKey, V>(...));
EnumMap的方法
- K – 密钥对象的类型
- V – 值对象的类型
方法 | 执行的动作 |
---|---|
清除() | 移除该Map中的所有映射。 |
clone() | 返回这个枚举图的浅层拷贝。 |
containsKey(Object key) | 如果这个Map包含指定键的映射,返回true。 |
containsValue(Object value) | 如果这个Map将一个或多个键映射到指定的值,则返回true。 |
entrySet() | 返回该Map中包含的映射的Set视图。 |
equals(Object o) | 将指定的对象与这个Map进行比较,看是否相等。 |
get(Object key) | 返回指定的键被映射到的值,如果此Map不包含键的映射,则返回空值。 |
hashCode() | 返回该Map的哈希代码值。 |
keySet() | 返回该Map中包含的键的Set视图。 |
put(K key, V value) | 将指定的值与该Map中指定的键关联起来。 |
putAll(Map<? extends K,? extends V> m) | 将指定Map中的所有映射复制到此Map中。 |
remove(Object key) | 如果存在的话,从这个Map中删除这个键的映射。 |
size() | 返回这个Map中的键值映射的数量。 |
values() | 返回该Map中包含的值的集合视图。 |
AbstractMap类中声明的方法
方法 | 说明 |
---|---|
isEmpty() | 如果该Map不包含键值映射,则返回true。 |
toString() | 返回该Map的一个字符串表示。 |
java.util.Map接口中声明的方法
方法 | 描述中心 |
---|---|
compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | 试图为指定的键和其当前的映射值计算一个映射(如果没有当前的映射,则为空)。 |
computeIfAbsent(K key, Function<? super K,? extends V> mappingFunction) | 如果指定的键还没有与一个值相关联(或者被映射为空),则尝试使用给定的映射函数计算其值,并将其输入此映射,除非为空。 |
computeIfPresent(K key, BiFunction<? super K,? super V,? extends V> remappingFunction) | 如果指定的键的值是存在的,并且不是空的,则尝试给定键和其当前的映射值来计算一个新的映射。 |
forEach(BiConsumer<? super K,? super V> action) | 对这个Map中的每个条目执行给定的动作,直到所有条目都被处理完,或者该动作抛出一个异常。 |
getOrDefault(Object key, V defaultValue) | 返回指定的键被映射到的值,如果这个Map不包含键的映射,则返回defaultValue。 |
merge(K key, V value, BiFunction<? super V,? super V,? extends V> remappingFunction) | 如果指定的键还没有与一个值关联,或者与空值关联,那么就将其与给定的非空值关联。 |
putIfAbsent(K key, V value) | 如果指定的键还没有与一个值相关联(或被映射为null),则将其与给定的值相关联并返回null,否则返回当前值。 |
remove(Object key, Object value) | 只有当指定的键当前被映射到指定的值时,才会删除该键的条目。 |
replace(K key, V value) | 只有当指定的键当前被映射到某个值时,才会替换该键的条目。 |
replace(K key, V oldValue, V newValue) | 只在当前映射到指定值的情况下替换指定键的条目。 |
replaceAll(BiFunction<? super K,? super V,? extends V> function) | 用在该条目上调用给定函数的结果替换每个条目的值,直到所有条目都被处理或该函数抛出一个异常。 |
EnumMap vs EnumSet
属性 | EnumMap | EnumSet |
---|---|---|
内部表示法 | EnumMap内部表示为数组。这种表示方法是紧凑和有效的。 | EnumSet内部表示为BitVector或比特序列 |
是否允许空元素? | 不允许有空键,但允许有空值。 | 不允许有空元素 |
是抽象类吗 | 不是 | 是的 |
实例化 | 由于EnumMap不是一个抽象类,它可以使用new操作符进行实例化。 | 作为一个抽象类,它没有一个构造函数。Enum集是使用它预定义的方法创建的,比如allOf(), noneOf(), of()等。 |
实现 | EnumMap是一个专门的Map实现,用于枚举类型的键。 | EnumSet是一个专门的Set实现,用于枚举类型。 |