EnumMap is a specialized implementation of the Map interface for enumeration types. It extends AbstractMap and implements the Map interface in Java. It belongs to java.util package. A few important features of EnumMap are as follows:
- EnumMap class is a member of the Java Collections Framework & is not synchronized.
- EnumMap is an ordered collection and they are maintained in the natural order of their keys(the natural order of keys means the order on which enum constants are declared inside enum type )
- It’s a high-performance map implementation, much faster than HashMap.
- All keys of each EnumMap instance must be keys of a single enum type.
- EnumMap doesn’t allow null key and throws NullPointerException when we attempt to insert the null key.
- Iterators returned by the collection views are weakly consistent: they will never throw ConcurrentModificationException and they may or may not show the effects of any modifications to the map that occur while the iteration is in progress.
- EnumMap is internally represented as arrays. This representation is extremely compact and efficient.
Syntax: Declaration
public class EnumMap<K extends Enum<K>,?V> extends AbstractMap<K,?V> implements Serializable, Cloneable
Parameters:
- Key object type
- Value object type
K must extend Enum, which enforces the requirement that the keys must be of the specified enum type.
The EnumMap class in Java is a specialized map implementation that is designed specifically for use with enum keys. An EnumMap is a compact, efficient, and fast alternative to using a HashMap with enum keys.
Here’s an example of how you can use the EnumMap class in Java:
Java
import java.util.EnumMap;
enum Days {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class EnumMapExample {
public static void main(String[] args) {
EnumMap<Days, String> schedule = new EnumMap<>(Days. class );
schedule.put(Days.MONDAY, "Work" );
schedule.put(Days.TUESDAY, "Work" );
schedule.put(Days.WEDNESDAY, "Study" );
schedule.put(Days.THURSDAY, "Study" );
schedule.put(Days.FRIDAY, "Relax" );
System.out.println(schedule.get(Days.MONDAY));
System.out.println(schedule.get(Days.FRIDAY));
}
}
|
output:
work
Relax
In this example, we define an enum type Days that represents the days of the week. We then create an EnumMap and add elements to it using the put method. Finally, we retrieve elements from the EnumMap using the get method and print the results to the console.
Advantages of using EnumMap:
- Efficient: The EnumMap class provides fast and efficient access to elements stored in the map, making it a good choice for use in performance-critical applications.
- Compact: The EnumMap class uses a compact representation for the map, which means that it requires less memory than a HashMap or a TreeMap.
- Type-safe: The EnumMap class only allows keys of a specified enum type, which means that it provides type-safe behavior and eliminates the need for casting.
- Sorted keys: The EnumMap class provides sorted keys, which means that the elements in the map are ordered by the order in which the enum constants are declared.
Disadvantages of using EnumMap:
- Limited to enum keys: The EnumMap class can only be used with keys of an enum type, which means that it’s not suitable for use with other types of keys.
- Immutable keys: The EnumMap class uses enum keys, which are immutable and cannot be modified once they are created.
EnumMap Hierarchy
Constructors of EnumMap
- EnumMap(Class keyType): The constructor is used to create an empty EnumMap with the specified keyType.
- EnumMap(EnumMap m): The constructor is used to create an enum map with the same keyType as the specified enum map, with initial mappings being the same as the EnumMap
- EnumMap(Map m): The constructor is used to create an enum map with initialization from the specified map in the parameter.
Example
Java
import java.util.EnumMap;
public class EnumMapExample {
public enum GFG {
CODE,
CONTRIBUTE,
QUIZ,
MCQ;
}
public static void main(String args[])
{
EnumMap<GFG, String> gfgMap
= new EnumMap<GFG, String>(GFG. class );
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" );
System.out.println( "Size of EnumMap in java: "
+ gfgMap.size());
System.out.println( "EnumMap: " + gfgMap);
System.out.println( "Key : " + GFG.CODE + " Value: "
+ gfgMap.get(GFG.CODE));
System.out.println(
"Does gfgMap has " + GFG.CONTRIBUTE + ": "
+ gfgMap.containsKey(GFG.CONTRIBUTE));
System.out.println(
"Does gfgMap has :" + GFG.QUIZ + " : "
+ gfgMap.containsValue( "Practice Quizes" ));
System.out.println( "Does gfgMap has :" + GFG.QUIZ
+ " : "
+ gfgMap.containsValue( null ));
}
}
|
Output
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
Basic Operations on EnumMap
Operation 1: Adding Elements
In order to add elements to the EnumMap, we can use put() or putAll() method as shown below.
Java
import java.util.EnumMap;
class GFG {
enum Color { RED, GREEN, BLUE, WHITE }
public static void main(String[] args)
{
EnumMap<Color, Integer> colors1
= new EnumMap<>(Color. class );
colors1.put(Color.RED, 1 );
colors1.put(Color.GREEN, 2 );
System.out.println( "EnumMap colors1: " + colors1);
EnumMap<Color, Integer> colors2
= new EnumMap<>(Color. class );
colors2.putAll(colors1);
colors2.put(Color.BLUE, 3 );
System.out.println( "EnumMap colors2: " + colors2);
}
}
|
Output
EnumMap colors1: {RED=1, GREEN=2}
EnumMap colors2: {RED=1, GREEN=2, BLUE=3}
Operation 2: Accessing the Elements
We can access the elements of EnumMap using entrySet(), keySet(), values(), get(). The example below explains these methods.
Java
import java.util.EnumMap;
class GFG {
enum Color { RED, GREEN, BLUE, WHITE }
public static void main(String[] args)
{
EnumMap<Color, Integer> colors
= new EnumMap<>(Color. class );
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);
System.out.println( "Key/Value mappings: "
+ colors.entrySet());
System.out.println( "Keys: " + colors.keySet());
System.out.println( "Values: " + colors.values());
System.out.println( "Value of RED : "
+ colors.get(Color.RED));
}
}
|
Output
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
Operation 3: Removing elements
In order to remove the elements, EnumMap provides two variations of the remove() method.
Example
Java
import java.util.EnumMap;
class GFG {
enum Color {
RED,
GREEN,
BLUE,
WHITE
}
public static void main(String[] args)
{
EnumMap<Color, Integer> colors
= new EnumMap<>(Color. class );
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);
int value = colors.remove(Color.WHITE);
System.out.println( "Removed Value: " + value);
boolean result = colors.remove(Color.RED, 1 );
System.out.println( "Is the entry {RED=1} removed? "
+ result);
System.out.println( "Updated EnumMap: " + colors);
}
}
|
Output
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}
Operation 4: Replacing elements
Map interface provides three variations of the replace() method to change the mappings of EnumMap.
Example
Java
import java.util.EnumMap;
class GFG {
enum Color {
RED,
GREEN,
BLUE,
WHITE
}
public static void main(String[] args)
{
EnumMap<Color, Integer> colors
= new EnumMap<>(Color. class );
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);
colors.replace(Color.RED, 11 );
colors.replace(Color.GREEN, 2 , 12 );
System.out.println( "EnumMap using replace(): "
+ colors);
colors.replaceAll((key, oldValue) -> oldValue + 3 );
System.out.println( "EnumMap using replaceAll(): "
+ colors);
}
}
|
Output
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}
Synchronized EnumMap
The implementation of an EnumMap is not synchronized. This means that if multiple threads access a tree set concurrently, and at least one of the threads modifies the set, it must be synchronized externally. This is typically accomplished by using the synchronizedMap() method of the Collections class. This is best done at the creation time, to prevent accidental unsynchronized access.
Map<EnumKey, V> m = Collections.synchronizedMap(new EnumMap<EnumKey, V>(...));
Methods of EnumMap
- K – Type of the key object
- V – Type of the value object
Method
|
Action Performed
|
clear() |
Removes all mappings from this map. |
clone() |
Returns a shallow copy of this enum map. |
containsKey?(Object key) |
Returns true if this map contains a mapping for the specified key. |
containsValue?(Object value) |
Returns true if this map maps one or more keys to the specified value. |
entrySet() |
Returns a Set view of the mappings contained in this map. |
equals?(Object o) |
Compares the specified object with this map for equality. |
get?(Object key) |
Returns the value to which the specified key is mapped, or null if this map contains no mapping for the key. |
hashCode() |
Returns the hash code value for this map. |
keySet() |
Returns a Set view of the keys contained in this map. |
put?(K key, V value) |
Associates the specified value with the specified key in this map. |
putAll?(Map<? extends K,?? extends V> m) |
Copies all of the mappings from the specified map to this map. |
remove?(Object key) |
Removes the mapping for this key from this map if present. |
size() |
Returns the number of key-value mappings in this map. |
values() |
Returns a Collection view of the values contained in this map. |
Methods Declared in AbstractMap Class
Method
|
Description
|
isEmpty() |
Returns true if this map contains no key-value mappings. |
toString() |
Returns a string representation of this map. |
Methods Declared in Interface java.util.Map
Method
|
Descriptionenter
|
compute?(K key, BiFunction<? super K,?? super V,?? extends V> remappingFunction) |
Attempts to compute a mapping for the specified key and its current mapped value (or null if there is no current mapping). |
computeIfAbsent?(K key, Function<? super K,?? extends V> mappingFunction) |
If the specified key is not already associated with a value (or is mapped to null), attempts to compute its value using the given mapping function and enters it into this map unless null. |
computeIfPresent?(K key, BiFunction<? super K,?? super V,?? extends V> remappingFunction) |
If the value for the specified key is present and non-null, attempts to compute a new mapping given the key and its current mapped value. |
forEach?(BiConsumer<? super K,?? super V> action) |
Performs the given action for each entry in this map until all entries have been processed or the action throws an exception. |
getOrDefault?(Object key, V defaultValue) |
Returns the value to which the specified key is mapped, or defaultValue if this map contains no mapping for the key. |
merge?(K key, V value, BiFunction<? super V,?? super V,?? extends V> remappingFunction) |
If the specified key is not already associated with a value or is associated with null, associates it with the given non-null value. |
putIfAbsent?(K key, V value) |
If the specified key is not already associated with a value (or is mapped to null) associates it with the given value and returns null, else returns the current value. |
remove?(Object key, Object value) |
Removes the entry for the specified key only if it is currently mapped to the specified value. |
replace?(K key, V value) |
Replaces the entry for the specified key only if it is currently mapped to some value. |
replace?(K key, V oldValue, V newValue) |
Replaces the entry for the specified key only if currently mapped to the specified value. |
replaceAll?(BiFunction<? super K,?? super V,?? extends V> function) |
Replaces each entry’s value with the result of invoking the given function on that entry until all entries have been processed or the function throws an exception. |
EnumMap vs EnumSet
Property
|
EnumMap
|
EnumSet
|
Internal Representation |
EnumMap is internally represented as arrays. The representation is compact and efficient. |
EnumSet is internally represented as BitVector or sequence of bits. |
Permits Null Elements? |
Null keys are not allowed but Null values are allowed. |
Null elements are not permitted. |
Is the Abstract Class? |
No |
Yes |
Instantiation |
Since EnumMap is not an abstract class, it can be instantiated using the new operator. |
It is an abstract class, it does not have a constructor. Enum set is created using its predefined methods like allOf(), noneOf(), of(), etc. |
Implementation |
EnumMap is a specialized Map implementation for use with enum type keys. |
EnumSet is a specialized Set implementation for use with enum types. |
See your article appearing on GeeksforGeek’s main page and help other Geeks.
Example :
Explanation
EnumMap is a specialized implementation of the Map interface in Java that is designed to be used with enums as keys. It is a high-performance implementation that is guaranteed to have constant time performance in many basic operations, such as get() and put().
The EnumMap class is a strongly typed Map implementation, which means that it can only be used with enums as keys. Each instance of EnumMap is associated with a specific enum class, and the key set of the map is a subset of the enum values. This ensures that the keys are always unique and well-defined.
One of the primary advantages of using EnumMap is its performance. Since it is designed specifically for use with enums, it can be optimized to take advantage of the unique properties of enums. For example, the EnumMap implementation uses a compact array-based data structure internally, which provides constant time performance for many basic operations.
Program
Java
import java.util.EnumMap;
import java.util.Map;
public class EnumMapExample {
enum Color {
RED, GREEN, BLUE
}
public static void main(String[] args) {
EnumMap<Color, String> colorMap = new EnumMap<>(Color. class );
colorMap.put(Color.RED, "FF0000" );
colorMap.put(Color.GREEN, "00FF00" );
colorMap.put(Color.BLUE, "0000FF" );
System.out.println( "Color map: " + colorMap);
String greenValue = colorMap.get(Color.GREEN);
System.out.println( "Value for GREEN: " + greenValue);
System.out.println( "All key-value pairs:" );
for (Map.Entry<Color, String> entry : colorMap.entrySet()) {
System.out.println(entry.getKey() + " -> " + entry.getValue());
}
}
}
|
Output
Color map: {RED=FF0000, GREEN=00FF00, BLUE=0000FF}
Value for GREEN: 00FF00
All key-value pairs:
RED -> FF0000
GREEN -> 00FF00
BLUE -> 0000FF
Here are some benefits of using EnumMap in Java:
Type safety: EnumMap is a strongly-typed implementation of Map that ensures that only enum constants can be used as keys. This provides type safety and reduces the risk of runtime errors caused by using the wrong key type.
Performance: EnumMap is designed to provide high performance when used with enums as keys. It uses a compact array-based data structure internally, which provides constant time performance for many basic operations.
Memory efficiency: Since EnumMap is designed to be used with enums as keys, it can be optimized to use less memory than other Map implementations. This can be particularly important when dealing with large numbers of enum constants.
Clear and concise code: Using EnumMap can make code clearer and more concise, particularly when dealing with operations that are specific to enums, such as iterating over all enum constants.
Standardized behavior: Since EnumMap is part of the Java Collections Framework, it provides a standardized way of using enums as keys in a Map. This can make code more consistent and easier to understand.
Overall, EnumMap provides a simple, efficient, and type-safe way to use enums as keys in a Map implementation. Its performance benefits and memory efficiency make it a good choice for applications that need to work with enums in this way.
Reference book:
“Java Performance: The Definitive Guide” by Scott Oaks is a comprehensive guide to optimizing the performance of Java applications. It includes a section on the use of specialized map implementations, including the EnumMap class.
Share your thoughts in the comments
Please Login to comment...