Java - How HashMap works in Java

http://javarevisited.blogspot.de/2011/02/how-hashmap-works-in-java.html

Because sometimes I can't open this page without proper proxy configuration, so I have to copy some content here.


HashMap in Java works on hashing principle. It is a data structure which allows us to store object and retrieve it in constant time O(1). In hashing, hash functions are used to link key and value in HashMap. Objects are stored by calling put(key, value) method of HashMap and retrieved by calling get(key) method. When we call put method, hashcode() method of key object is called so that hash function of map can find a bucket location to store value object, which is actually index of internal array, known as table. HashMap internally store mapping in form of Map. Entry object which contains both key and value object. When you want to retrieve the object, you call get() method and pass key object. This time again key object generate same hash code (it's mandatory for it to do so to retrieve object and that's why HashMap keys are immutable e.g. String) and we end up at same bucket location. If there is only one object then it is returned and that's your value object which you have stored earlier. Things get little tricky when collisions occurs. Since internal array of HashMap is of fixed size, and if you keep storing objects, at some point of time hash function will return same bucket location for two different keys, this is called collision in HashMap. In this case, a linked list is formed at that bucket location and new entry is stored as next node. If we try to retrieve object from this linked list, we need an extra check to search correct value, this is done by equals() method. Since each node contains an entry, HashMap keep comparing entry's key object with passed key using equals() and when it return true, Map returns corresponding value. Since searching in linked list is O(n) operation, in worst case hash collision reduce a map to linked list. This issue is recently addressed in Java 8 by replacing linked list to tree to search in O(logN) time.


using immutable, final object with proper equals() and hashcode() implementation would act as perfect Java HashMap  keys and improve performance of Java HashMap  by reducing collision. Immutability also allows caching hashcode of different keys, so that overall retrieval process will be very fast. So it's suggested that String and various wrapper classes e.g. Integer can be very good keys in Java HashMap.


What happens On HashMap in Java if the size of the HashMap  exceeds a given threshold defined by load factor ?

If the size of the Map exceeds a given threshold defined by load-factor e.g. if load factor is .75, it will act to re-size the map once it filled 75%. Similar to other collection classes like ArrayList,  Java HashMap re-size itself by creating a new bucket array of size twice of previous size of HashMap , and then start putting every old element into that new bucket array. This process is called rehashing because it also applies hash function to find new bucket location.

There is potential race condition exists while resizing HashMap in Java. If two thread at the same time found that now HashMap needs resizing and they both try to resizing. On the process of resizing of HashMap in Java , the element in bucket which is stored in linked list get reversed in order during their migration to new bucket, because Java HashMap doesn't append the new element at tail instead it append new element at head to avoid tail traversing. If race condition happens then you will end up with an infinite loop.

How null key is handled in HashMap? Since equals() and hashCode() are used to store and retrieve values, how does it work in case of null key?

Null key is handled specially in HashMap, there are two separate method for that putForNullKey(V value) and getForNullKey(). Later is offloaded version of get() to look up null keys.  Null keys always map to index 0.  This null case is split out into separate methods for the sake of performance in the two most commonly used operations (get and put), but incorporated with conditionals in others. In short, equals() and hashcode() method are not used in case of null keys in HashMap.

HashMap Changes in JDK 1.7 and JDK 1.8

There is some performance improvement done on HashMap and ArrayList from JDK 1.7, which reduce memory consumption. Due to this, empty Map are lazily initialized and will cost you less memory.

Also from JDK 1.8 onwards, HashMap has introduced an improved strategy to deal with high collision rate. Since a poor hash function always return location of same bucket, which can turn a HashMap into linked list, and convert get() method to perform in O(n) instead of O(1). Java now internally replace linked list to a binary true once certain threshold is breached. This ensures performance or order O(log(n)) even in worst case where hash function is not distributing keys properly.


你可能感兴趣的:(Java - How HashMap works in Java)