EnumMap vs HashMap in Java

1. Introduction

Java collections framework offers different types of Map implementations for storing key-value pairs. EnumMap is a specialized Map implementation designed for use with keys of enum type. It is internally implemented as an array, with the ordinal values of the enums serving as array indices. On the other hand, HashMap is a general-purpose Map implementation that can store any type of objects as keys and uses hashing for storing its entries.

2. Key Points

1. EnumMap keys are always of an enum type, and its elements are ordered by their natural order (the order in which the enum constants are declared).

2. HashMap can have any object type as a key and stores elements based on the hashcode of the keys.

3. EnumMap is typically faster and more compact than HashMap, especially when the key's universe is small.

4. EnumMap does not allow null keys; HashMap allows one null key.

5. Iterators of EnumMap return elements in the natural order of the keys (the order in which the enums are declared), while the order of HashMap elements cannot be guaranteed.

3. Differences

EnumMap HashMap
Keys must be of a single enum type. It can have any object type as keys.
Internally represented as arrays, leveraging the natural ordering of enum constants for efficiency. Uses a hash table structure to store key-value pairs.
It cannot contain null keys. Allows one null key.
Iteration order is maintained according to the natural order of the enum keys. Iteration order is not guaranteed and can change over time.
Offers constant-time performance for basic operations like get and put, assuming the universe of the key is reasonably small. Under ideal conditions, it offers constant-time performance for get and put operations, but performance can be affected by the hash function and initial capacity.
Specifically optimized for use with enum keys, it is a highly efficient and compact implementation for enum-based maps. This is a general-purpose Map implementation with no type restrictions on keys or values, offering flexibility at the expense of a larger memory footprint.

4. Example

// Import the necessary classes
import java.util.EnumMap;
import java.util.HashMap;
import java.util.Map;

// An enumeration of example days
enum Day {
    MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

public class MapComparison {
    public static void main(String[] args) {
        // Step 1: Create an EnumMap
        Map<Day, String> enumMap = new EnumMap<>(Day.class);

        // Step 2: Create a HashMap
        Map<Day, String> hashMap = new HashMap<>();

        // Step 3: Populate the EnumMap
        enumMap.put(Day.MONDAY, "Start of the work week");
        enumMap.put(Day.FRIDAY, "End of the work week");

        // Step 4: Populate the HashMap
        hashMap.put(Day.MONDAY, "Start of the work week");
        hashMap.put(Day.FRIDAY, "End of the work week");

        // Step 5: Print the maps
        System.out.println("EnumMap: " + enumMap);
        System.out.println("HashMap: " + hashMap);
    }
}

Output:

EnumMap: {MONDAY=Start of the work week, FRIDAY=End of the work week}
HashMap: {MONDAY=Start of the work week, FRIDAY=End of the work week}

Explanation:

1. An EnumMap is created with Day as the key type, ensuring that keys are of enum type and that they will be stored in the natural order of the enum.

2. A HashMap is created which can store any type of keys, but for the purpose of comparison, we use the same Day enum as keys.

3. Both enumMap and hashMap are populated with the same key-value pairs.

4. The maps are printed showing that they contain the same entries. The EnumMap maintains the natural enum order, while the HashMap order is not guaranteed.

5. When to use?

Use EnumMap when you have an enum type as keys and want to combine speed with compactness. It's also beneficial when you want to maintain the keys' natural order.

Use HashMap when dealing with non-enum keys or when working with Maps that need to store various types of keys.

Comments