Brief analysis of JAVA HashMap source code

Source: Internet
Author: User
Tags array length

Introduction

HashMap is used frequently in key-value pairs, how does it implement key-value storage?


A Entry

Entry is an internal interface in the map interface that implements key-value-to-store key. In HashMap, there are entry implementation classes, called entry. The entry class is simple, containing key,value, an externally introduced hash, and a reference to the next entry object, similar to the note node in the linked list of the data structure secondary.

Properties and constructors for the entry class:

Final K Key; V value; Entry<k,v> Next;int hash;/** * Creates new Entry.    */entry (int h, K K, v V, entry<k,v> N) {value = V;    Next = n;    key = k; hash = h;}


Initialization of two HashMap
Public hashmap (Int initialcapacity, float loadfactor)  {    if   (initialcapacity < 0)         throw new  IllegalArgumentException ("illegal initial capacity: "  +                                              initialcapacity);    if  (initialcapacity > maximum_capacity)         initialCapacity = MAXIMUM_CAPACITY;     if  (loadfactor <= 0 | |  float.isnan (loadfactor))         throw new  IllegalArgumentException ("illegal load factor: "  +                                             loadfactor);    this.loadfactor = loadfactor;     threshold = initialcapacity;    init ();}

This is one of the constructors of HashMap, and other constructors refer to this constructor for initialization. Parameter initialcapacity refers to the initial size of the table array in HashMap, and the parameter loadfactory refers to the ratio of the hashmap to the length of the array (for example: the default value of array length is 16, The default value of Loadfactory is 0.75, and if the key value pairs stored in HashMap are entry more than 12, they will be scaled up to twice times the length of the current array. The constructor does not initialize the array, and it is only possible to determine whether to initialize or expand it within the action method of put.


Three table array

There is a concept in HashMap called threshold (actual capacity), the actual capacity refers to the number of entry allowed in the HashMap, which is the length of the array table built into the HashMap *load (load factor) Come Its role is to ensure the efficiency of hashmap.

Table array is another key to hashmap implementation of key-value pairs, how are key-value pairs stored? Please look

(Key,value) is the entry object, and the table array is used to hold the entry object.

Initialization of the array:

private static int rounduptopowerof2 ( Int number)  {    return number >= MAXIMUM_CAPACITY             ? MAXIMUM_CAPACITY             :  (number > 1)  ?  Integer.highestonebit ((number - 1)  << 1)  : 1;} Private void inflatetable (int tosize)  {    // Find a  power of 2 >= tosize    int capacity =  ROUNDUPTOPOWEROF2 (tosize);    threshold =  (int)  math.min (capacity * &NBSP;LOADFACTOR,&NBSP;MAXIMUM_CAPACITY&NBSP;+&NBSP;1);    table = new  Entry[capacity];    inithashseedasneeded (capacity);} 

The Inflatetable method is called when the array is not initialized in a method such as put, and the input parameter is the initialcapacity of the initial setting. In fact, he would call the RoundUpToPowerOf2 method to return a power of a minimum of 2 greater than the initial capacity (one of the reasons is that it is convenient to get the array position where entry is located).


Four-Put method
Public v put (K key, v value)  {    if  (table ==  empty_table)  {        inflatetable (threshold);     }    if  (key == null)          return putfornullkey (value);     int hash = hash (key);     int i = indexfor (hash, table.length);    for  ( Entry<k,v> e = table[i]; e != null; e = e.next)  {         Object k;         if  (e.hash == hash &&  (k = e.key)  == key | |  key.equals (k))  {            V  Oldvalue = e.value;            e.value = value;             e.recordaccess (This);             return oldValue;         }    }    modcount++;    addentry (Hash,  key, value, i);     return null;} Private v putfornullkey (V value)  {    for  (entry<k,v>  E = table[0]; e != null; e = e.next)  {         if  (e.key == null)  {             V oldValue = e.value;             e.value = value;             e.recordaccess (This);             return oldValue;         }    }    modcount++;    addentry (0,  null, value, 0);     return null;} Void addentry (Int hash, k key, v value, int bucketindex)  {     if  (Size >= threshold)  &&  (null != table[ Bucketindex])  {        resize (2 * table.length);         hash =  (Null != key)  ? hash (key)   :  0;        bucketindex = indexfor (hash,  Table.length);     }    createentry (haSh, key, value, bucketindex);} Void createentry (Int hash, k key, v value, int bucketindex)  {     entry<k,v> e = table[bucketindex];    table[ Bucketindex] = new entry<> (hash, key, value, e);     size++;}

In the Put method, the array is first judged to be empty, and if empty, the arrays are initialized.

Next, determine if key is null, and if NULL, use the second method to put a key-value pair.

Next, the key is hashed to get a value, and then the value is processed (Indexfor method) to get the position in the array.

The next step is to traverse the linked list where the array is located, if the hash of the key is the same as the hash of the incoming key and (the key memory address is equal or equal to the Equals method), it means that the value in the linked list is updated and the old value value is returned.

If none of the above methods work, then a third method is called, creating a new entry object.


In the Putfornullkey method, we see that it is specifically set for a null value, and the hash of the null value is always 0, so the entry object with the key null must be in the No. 0 position of the array. Similarly, if the update is found, it is added if it is not found.


Calling the AddEntry method means adding a entry to the list of arrays, so you can start by judging whether the number of entry that already exists exceeds the actual amount of capacity. If it is exceeded, the resize method is called to enlarge the array by twice times, noting that the entry that have been deposited will be re-ranked after the expansion because the Indexfor method is related to the length of the array when it was deposited. A fourth method is then called.


The Createentry method is simple, which is to put the new entry into the array after placing the linked list head that was originally stored in the array into the new entry. From here we can see that HASHMAP does not guarantee the order problem.


The Get method and the contains method are consistent with the Put method, i.e. the position of the linked header in the array whose value is located by the hash of the key, and then the Equals method to determine whether the value exists.


Five other
Hash method Final int hash (object k)  {    int h = hashSeed;     if  (0 != h && k instanceof string)  {         return sun.misc.hashing.stringhash32 ((String)  k);     }    h ^= k.hashcode ();    //  this function ensures that hashcodes that differ only by     // constant multiples at each bit position have a  bounded    // number of collisions  (approximately 8 at  Default load factor) .    h ^=  (h >>> 20)  ^   (h >>> 12);    return h ^  (h >>>  7)  ^  (h &GT;&GT;&GT;&NBSP;4);} 

The final return value in the hash method is related to the Hashcode method of key.


Summarize

The size of the final array initialization will be greater than or equal to the power of the smallest 2 of your incoming initial capacity.

The reason that key is null or value NULL can be stored in HashMap is due to a separate operation on the null value.

In the list of tables in the table array, the common denominator for each entry is the same as the hash (key.hashcode) portion of key.

Note the hashcode of key and the override of the Equals method when you want to have two keys map an object, because the criteria for determining the equality of keys are (hashcode equals + (equal of memory or equals)).

The first key-value pairs are placed at the end of the list.

When the array does not have a linked list, HashMap performance is best for O (1). And the worst is O (threshould).

Brief analysis of JAVA HashMap source code

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.