Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it better to use Objects or integers as HashMap keys?

How does hashing of objects work in java's HashMap? I was thinking if it is more efficient to use integers as keys compared to Strings or if it does not matter.

If I have:

String str = "hello";
Object helloObject = new Object();

What is better in case of String? Use integer key:

HashMap<Integer, Object> hashes = new HashMap<Integer, Object>();
hashes.put(str.hashCode(), helloObject);

or use String key?

HashMap<String, Object> hashes = new HashMap<String, Object>();
hashes.put(str, helloObject);

What is more efficient from point of inserting and what from point of searching?

like image 931
Samuel Avatar asked Nov 19 '13 14:11

Samuel


People also ask

What classes should we prefer to use a key in HashMap?

Since the String class is immutable, you cannot modify the value of a String once it is created. Therefore, it is recommended to use a String variable to hold keys in hash a map.

Can we use integer as key in HashMap?

It can store different types: Integer keys and String values or same types: Integer keys and Integer values. HashMap is similar to HashTable, but it is unsynchronized. It is allowed to store null keys as well, but there can only be one null key and there can be any number of null values.

Can I use object as a key in HashMap?

Yes, we can use any object as key in a Map in java but we need to override the equals() and hashCode() methods of that object class.

Why an object used as key in HashMap should be immutable?

Immutabiility is required, in order to prevent changes on fields used to calculate hashCode() because if key object return different hashCode during insertion and retrieval than it won't be possible to get object from HashMap.


2 Answers

The first thing to get right should be correctness, not the efficiency: this code

HashMap<Integer, Object> hashes = new HashMap<Integer, Object>();
hashes.put(str.hashCode(), helloObject);

is incorrect (in addition to being inefficient *).

Recall that hash codes are not unique. The only requirement as per Java documentation is for hash codes of equal objects to be the same. However, objects with the same hash code are not necessarily equal. As the result, changing your hash map's key from String to Integer changes the semantics: two entirely different objects may be considered the same key absolutely arbitrarily, based on their hash code.


* In case you are curious why the above code snippet is inefficient, there is an autoboxing going on: hashCode() returns a primitive int, which is wrapped in a java.lang.Integer by the compiler. This often leads to creating an unwanted object in a situation where no additional object is created when you use a String.
like image 175
Sergey Kalinichenko Avatar answered Nov 13 '22 21:11

Sergey Kalinichenko


Keep in mind that two strings with the same hash code might not be equal.

If you use the string's hashCode instead of the string itself then two different strings can produce the same map's key and that might result in a strange behavior.

Try this code and see what I mean.

Map<Integer, String> map = new HashMap<Integer, String>();
map.put("FB".hashCode(), "FB");
map.put("Ea".hashCode(), "Ea");

System.out.println(map.get("FB".hashCode()));

will output

Ea

because

"FB".hashCode() == "Ea".hashCode() // is true

Thus you should better use the String as the key.

like image 36
René Link Avatar answered Nov 13 '22 21:11

René Link