Wednesday, March 11, 2015

How HashMap works in java #interview

A map is an object that maps keys to values and HashMap works on the "principle of hashing".

Hashing is a way to assigning a unique code for any variable/object after applying any formula/algorithm on its properties.
Hash function should return the same hash code each and every time, when function is applied on same or equal objects. In other words, two equal objects must produce same hash code consistently.

hashCode() and equals() methods have been defined in Object class which is parent class for java objects. For this reason, all java objects inherit a default implementation of these methods.

Usage of hashCode() and equals()

hashCode() method is used to get a unique integer for given object. This integer is used for determining the bucket location, when this object needs to be stored in some HashTable like data structure. By default, Object’s hashCode() method returns and integer representation of memory address where object is stored.

equals() method, as name suggest, is used to simply verify the equality of two objects. Default implementation simply check the object references of two objects to verify their equality.
  • Entry Class in HashMap 
    • HashMap has an inner class Entry.Entry class has key and value mapping stored as attributes. Key has been marked as final and two more fields are there: next and hash.
      Before going into put() method’s implementation, it is very important to learn that instances of Entry class are stored in an array. HashMap class defines this variable as:



      transient Entry[] table;
      put() method of HashMap
      Parameters:

          key key with which the specified value is to be associated
          value value to be associated with the specified key
      Returns:
          the previous value associated with key, or null if there was no mapping for key. (A null return can also indicate that the map previously associated null with key.)


      Step 1: key object is checked for null. If key is null, value is stored in table[0] position. Because hash code for null is always 0.
      Step 2
      : hash value is calculated using key’s hash code by calling its hashCode() method.This hash value is used to calculate index in array for storing Entry object .
      Step 3
      : indexFor(hash, table.length) function is called to calculate exact index position for storing the Entry object.
      Step 4:
      Now, as we know that two unequal objects can have same hash code value, how two different objects will be stored in same array location [called bucket].
      Answer is LinkedList. If you remember, Entry class had an attribute “next”. This attribute always points to next object in chain. This is exactly the behavior of LinkedList.
      • So, in case of collision, Entry objects are stored in LinkedList form. When an Entry object needs to be stored in particular index, HashMap checks whether there is already an entry?? If there is no entry already present, Entry object is stored in this location.
      • If there is already an object sitting on calculated index, its next attribute is checked. If it is null, and current Entry object becomes next node in LinkedList. If next variable is not null, procedure is followed until next is evaluated as null.
      • What if we add the another value object with same key as entered before. Logically, it should replace the old value. How it is done? Well, after determining the index position of Entry object, while iterating over LinkedList on calculated index, HashMap calls equals method on key object for each Entry object. All these Entry objects in LinkedList will have similar hash code but equals() method will test for true equality. If key.equals(k) will be true then both keys are treated as same key object. This will cause the replacing of value object inside Entry object only.
       
      get() method of HashMap

      Now we have got the idea, how key-value pairs are stored in HashMap. Next big question is : what happens when an object is passed in get method of HashMap? How the value object is determined?

      Answer we already should know that the way key uniqueness is determined in put() method , same logic is applied in get() method also. The moment HashMap identify exact match for the key object passed as argument, it simply returns the value object stored in current Entry object.

      If no match is found, get() method returns null.

      code is same as put() method till if (e.hash == hash && ((k = e.key) == key || key.equals(k))), after this simply value object is returned.


      *Hash tables deal with collisions in one of two ways*

      1. By having each bucket contain a linked list of elements that are hashed to that bucket. This is why a bad hash function can make lookups in hash tables very slow.
      2. If the hash table entries are all full then the hash table can increase the number of buckets that it has and then redistribute all the elements in the table. The hash function returns an integer and the hash table has to take the result of the hash function and mod it against the size of the table that way it can be sure it will get to bucket. so by increasing the size it will rehash and run the modulo calculations which if you are lucky might send the objects to different buckets.

      Java uses both option 1 and 2 in its hash table implementations.

      source: grepcode, HowtodoinJava ,Stackoverflow






Creating mirror of BST