Java enummap vs hashmap

Difference between EnumMap and HashMap in Java? Example

What is the difference between EnumMap and HashMap in Java is the latest Java collection interview question which has been asked to a couple of my friends? This is one of the tricky Java questions, especially if you are not very much familiar with EnumMap in Java, which is not uncommon, given you can use it with only Enum keys. The main difference between EnumMap and HashMap is that EnumMap is a specialized Map implementation exclusively for Enum as key. Using Enum as a key allows doing some implementation level optimization for high performance which is generally not possible with other objects as key.

We have seen a lot of interview questions on HashMap in our article How HashMap works in Java but what we missed there is this question which is recently asked by some of my friends. Unlike HashMap , EnumMap is not applicable for every case but it’s best suited when you have Enum as key.

We have already covered the basics of EnumMap and some EnumMap examples in my last article What are EnumMap in Java and In this post, we will focus on key differences between HashMap and EnumMap in Java.

EnumMap vs HashMap

Before looking at the differences between EnumMap and HashMap , few words about What is common between them. Both of them implements Map interface so they can be used in all methods which accept Map and data can be accessed using common Map methods e.g. get() and put(). Internally EnumMap is represented using Array and provides constant-time performance for common methods e.g. get() or put() . Now let’s see few differences between EnumMap vs HashMap :

1) As said earlier, the first and foremost difference between EnumMap and HashMap is that EnumMap is optimized for enum keys while HashMap is a general-purpose Map implementation similar to Hashtable. you can not use any type other than Enum as a key in EnumMap but you can use both Enum and any other Object as a key in HashMap.

2) Another difference between EnumMap and HashMap is performance. as discussed in the previous point, due to specialized optimization done for Enum keys, EnumMap is likely to perform better than HashMap when using an enum as a key object.

3) One more thing which can be considered as the difference between HashMap and EnumMap is the probability of Collision. Since Enum is internally maintained as an array and they are stored in their natural order using ordinal(), as shown in the following code which is taken from the put() method of EnumMap

int index = ((Enum)key).ordinal(); Object oldValue = vals[index]; vals[index] = maskNull(value);

These were some notable differences between EnumMap and HashMap in Java. In short, EnumMap is best suited for enum keys, for which it has optimized and performed better than HashMap in Java. Use EnumMap whenever you can use enum as keys.

Читайте также:  Javascript div border radius

Источник

Why use EnumMap instead of HashMap

Enum maps are represented internally as arrays. This representation is extremely compact and efficient.

Implementation note: All basic operations execute in constant time. They are likely (though not guaranteed) to be faster than their HashMap counterparts.

Pretty much what I was copying 🙂 I suggest OP looks into the source for EnumMap in order to see the shortcuts that can be taken when the entire «usage space» is known in advance (since enum s are constant.)

There are also third-party libraries with similar specialized implementations of Map (and other types of Collections) for constrained key or value types such as int , all for the purpose of efficiency.

The main reason for EnumMap is that it is specifically optimised for enums. Further benefits are mentioned below.

1) First and foremost difference between EnumMap and HashMap is that EnumMap is optimized for enum keys while HashMap is a general purpose Map implementation similar to Hashtable. you can not use any type other than Enum as key in EnumMap but you can use both Enum and any other Object as key in HashMap.

2) Another difference between EnumMap and HashMap is performance. as discussed in the previous point, due to specialized optimization done for Enum keys, EnumMap is likely to perform better than HashMap when using enum as key object.

3) One more thing which can be considered as the difference between HashMap and EnumMap is the probability of Collision. Since Enum is internally maintained as array and they are stored in their natural order using ordinal(), as shown in following code which is taken from put() method of EnumMap

int index = ((Enum)key).ordinal(); Object oldValue = vals[index]; vals[index] = maskNull(value); 

Источник

HashMap vs EnumMap scenario

I am in a dilemma between 2 ways of implementing something and wondered what is more efficient (memory and\or time wise). I need to get requests containing an Op-code and map it to a Category. There are between 1000 to 2000 Op-codes only 3-4 categories. The mapping is predefined and well known. Solution 1: using HashMap It’s simple but I think it’s wasting too much memory because its many to few mapping. Solution 2: Predefine an Enumartion:

I read that EnumMap is compact and efficient. Important note: The Maps in both solutions are initiated once and doesn’t change throughout the process life. What do you think?

Читайте также:  Java new map entry

Are you considering hard-coding the op-code—category mapping in a Java source file, or could you have the data stored in a database?

Where are the op-code—category mappings currently located — are they in a file of some sort or just written on paper? What I’m trying to imply is that if the information is in electronic format, you should really consider importing it to a database (or even a property file), because hard-coding 2000 values seems like a bad idea (in general).

2 Answers 2

Consecutive op codes

If your op-codes are consecutive integers between 0 and 2000, you don’t need a map. Use the op-codes as indexes of an array, like so (do note that the hard-coding is for sake of example brevity only):

Category[] mapping = < Category.A, // Opcode 0 Category.A, // Opcode 1 Category.B, // Opcode 2 . >; int opcode = . Category category = mapping[opcode]; 

Sparse op codes

If your op-codes are not consecutive and sparse (with large gaps), your enum solution might work as you could encode the op-codes as enum and use the enum ordinal for the array index:

Category[] mapping = < Category.A, // Opcode 13 (the first possible opcode) Category.A, // Opcode 42 (the second possible opcode) Category.B, // Opcode 88 (the third possible opcode) . >; int opcode = opcodeEnum.ordinal(); Category category = mapping[opcode]; 

Note that in the latter case, EnumMap is pretty much doing the exact same thing as the above solution although using up more memory, as it contains some caches for Map.entrySet() and other calls.

When to prefer the above over HashMap

In any case, the array or EnumMap solutions should be preferred over the HashMap solution if you will provide a category for every op code in the possible op code space. If you only categorise 1% of your op codes, then creating the array for the entire op code space will be wasting too much memory, and a HashMap might be better.

Regarding your second solution with Category[], you mean that every cell in the array will hold a pointer for the pertinent Category reference?

I updated the answer. The opcodes don’t correspond to the array indexes, but the opcodes’ ordinal within the enum definition (the order of definition) does, if you enumerate opcodes strictly ascendingly.

Do you really think this is a readable and maintainable solution when the array could have 2000 hard-coded values and for each of these the index would need to be manually marked as a comment?

Thank you for the straw-man argument. My honest intention was to point out that the solution you’ve provided to the OP’s problem is not sustainable because you’ve made the mapping implicit instead of explicit, which is really is a problem when you have 2000 op-codes. How will the maintenance programmer check the category of op-code 1234 by looking at the code?

Solution 1: using HashMap It’s simple but I think it’s wasting too much memory because its many to few mapping.

Actually, it’s probably no more than 10-20KB which is barely a crumb these days. The HashMap is just an array of pointers.

Читайте также:  Php сгенерировать строку определенной длины

However, if you’re converting int to Integer all the time, that’s probably not the best thing in the world.

I don’t think this actually helps you out, because now you need to map opcodes to CategoryEnum .

If the numerical values of the opcodes aren’t very large (a few thousand), then by far the best option is just to use a Category[] and index the opcodes in to the array directly. The length of the array needs to be the value of the highest opcode +1.

If the numerical values are more than a few thousand, then it isn’t that difficult to program your own simple hashtable, just for retrievals. (DIY is kind of like Java heresy, but until they give us primitive generics we are stuck.)

There are some libraries out there with primitive collections as well.

Источник

Difference between EnumMap and HashMap in Java

EnumMap is introduced in JDK5. It is designed to use Enum as key in the Map. It is also the implementation of the Map interface. All of the key in the EnumMap should be of the same enum type. In EnumMap , key can’t be null and any it will throw NullPointerException.

EnumMap internally using as arrays, this representation is extremely compact and efficient.

HashMap is also the implementation of the Map interface. It is used to store the data in Key and Value form. It can contain one null key and multiple null values . In HashMap, keys can’t be a primitive type. Java HashMap implementation provides constant-time performance for the basic operations (get and put), assuming the hash function disperses the elements properly among the buckets.

A specialized Map implementation for use with enum type keys

HashMap is also the implementation of the Map interface.

It can have one null key and multiple null values

All operations execute in constant time therefore it is faster than HashMap

It is slower than HashMap

It uses Hashtable internally

EnumMap stores keys in the natural order of their keys

Example of EnumMap

import java.util.ArrayList; import java.util.EnumMap; import java.util.List; import java.util.Map; public class EnumMapExample < public enum LaptopEnum < HCL, DELL, IBM >; public static void main(String[] args) < // create enum map EnumMap map = new EnumMap(LaptopEnum.class); map.put(LaptopEnum.HCL, "100"); map.put(LaptopEnum.DELL, "200"); map.put(LaptopEnum.IBM, "300"); // print the map for (Map.Entry m : map.entrySet()) < System.out.println(m.getKey() + " " + m.getValue()); >> >

Example of HashMap

import java.util.ArrayList; import java.util.EnumMap; import java.util.HashMap; import java.util.List; import java.util.Map; public class HashMapExample < public static void main(String[] args) < // create Hash map Map map = new HashMap(); map.put("HCL", "100"); map.put("DELL", "200"); map.put("IBM", "300"); // print the map for (Map.Entry m : map.entrySet()) < System.out.println(m.getKey() + " " + m.getValue()); >> >

Источник

Оцените статью