Java container HashMap and HashSet learning

Source: Internet
Author: User
Tags object object

Java learning, see Hashmap,hashset class, in line with not only to stay on the level (many companies interview to ask the bottom), learn the JDK source code, record notes.

Source code from jdk1.7 under the Src.zip

HashMap is a type of key-value pair that provides a key-value data structure that implements the map interface, where the value of key is unique, that is, a key can only be mapped to a unique value at a time.

See some of the members (not all)

static final int default_initial_capacity = 1 << 4; aka 16static final float default_load_factor = 0.75f;transient entry<k,v>[] table = (entry<k,v>[]) Empty_ta ble;final float loadfactor;int threshold;

Table is an array structure, where each pair of mappings is put here.

Entry<k,v> implements Map.entry, which is a Key-value key-value pair in the map, to see exactly (and other methods, omitted here)

Static Class Entry<k,v> implements Map.entry<k,v> {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; }        ...

Entry is the inner class of HashMap, its members have Key,value,hash, this next is a chain structure, entry contains the basic mapping Hashcode () method, OK clear its composition

The HASHMAP data structure is also


We now care about the HashMap put (K key, V value) method

Public V put (K key, V value) {        if (table = = empty_table) {//table is empty, request space            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) {//If the key of the Entry to be inserted has occurred, replace depreciation to insert the value of Entry and return oldvalue            objec t k;            if (E.hash = = Hash && (k = e.key) = = Key | | key.equals (k))) {//hash value equality may be a collision, judging equality may also override the Equals method, so add | |                V oldValue = e.value;                E.value = value;                E.recordaccess (this);                return oldValue;            }        }        modcount++;        AddEntry (hash, key, value, I);//Add to the list header        return null;    }
As can be seen above, according to the key to determine the storage location of each entry, you can take value as a subsidiary of the key, look at the 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, differ only to        //constant multiples at each bit position has a bounded< c7/>//number of collisions (approximately 8 at default load factor).        H ^= (H >>>) ^ (h >>> N);        Return h ^ (H >>> 7) ^ (H >>> 4);    }
That is, by means of a hash function (as for hashcode and the practice of getting H is unclear ...). ), the key is mapped to a hash value of type int, and then the subscript of key in the table array is determined by indexfor

static int indexfor (int h, int length) {        //Assert integer.bitcount (length) = = 1: "Length must be a non-zero power of 2 ";        Return H & (length-1);    }
This length is a power of 2 and solves the case where the previous hash value is larger than the array length.

And look at the AddEntry method:

void AddEntry (int hash, K key, V value, int bucketindex) {        if (size >= threshold) && (null! = Table[bucket Index]) {            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) {    //note that inserting entry right here is in the head of the list, you can see the entry constructor above    // E is the head of the previous, then the new entry as next.        entry<k,v> e = Table[bucketindex];        Table[bucketindex] = new entry<> (hash, key, value, e);        size++;}
You can see that if different keys are mapped to the same hash value, the call to AddEntry is made, and then the Chain Address method as a method of dealing with conflicts, the new object is placed in the list header

at the same time, when the number of entry added when you arrive at threshold, the table will be resize, There is a transfer method in resize to copy the contents of the old table to the new table. Double the size of the table

<span style= "FONT-SIZE:14PX;" >void Resize (int newcapacity) {        entry[] oldtable = table;        int oldcapacity = oldtable.length;        if (oldcapacity = = maximum_capacity) {//If you have reached 1 << 30, you can no longer expand the            threshold = integer.max_value;//(1 << 31)- 1            return;        }        entry[] newtable = new entry[newcapacity];        Transfer (newtable,inithashseedasneeded (newcapacity));  Copy the current table contents to the new table table        = newtable;        threshold = (int) math.min (newcapacity * loadfactor, maximum_capacity + 1);//Recalculate Threshold}</span>
so far, the whole put process of hashmap has been finished.

Get method:

Public V get (Object key) {        if (key = = null)            return Getfornullkey ();        entry<k,v> Entry = Getentry (key);        return NULL = = entry? Null:entry.getValue ();    } Final entry<k,v> getentry (Object key) {        if (size = = 0) {            return null;        }        int hash = (key = = null)? 0:hash (key);        for (entry<k,v> e = table[indexfor (hash, table.length)];         Table[indexfor (hash, table.length)] is the value of the indexfor operation is mapped directly to the index of the array             E! = null;        Search the Entry chain for the next Entry             e = e.next) {            Object k;            if (E.hash = = Hash &&                (k = e.key) = = Key | | (Key! = null && key.equals (k)                ))) return e;        }        return null;    }

Find the process: Locate the mapped point and then compare it with the elements in the list to ensure that the target value is found. Because it is a hash table, there will be multiple values mapped to the same index inside, so there is also a link to the list of elements in contrast.

when  HASHMAP&NBSP; BUCKET&NBSP; ENTRY&NBSP; entry -- ENTRY&NBSP; When the chain, the   at this time; HASHMAP&NBSP; table there is no link list drop-down in the array.

Simple summary HashMap:

HashMapat the bottom of theKey-valueas a whole to deal with, this whole is aEntryobject. HashMapThe bottom layer uses aentry[]array to hold all theKey-valueYes, when you need to store aEntryobject, it is based on theHashalgorithm to determine where it is stored, when it is necessary to remove aEntry, it will also be based onHashThe algorithm finds its storage location and directly extracts theEntry. This shows:HashMapThe reason why it is possible to quickly save and take what it containsEntry, exactly like what the mother taught us in real life: different things need to be put in different places, and it can be found quickly when needed.

the realization of HashSet

for  HASHSET&NBSP; HASHMAP&NBSP; implemented, Span style= "font-family:arial" >HASHSET&NBSP; bottom adopts   HASHMAP&NBSP; HASHSET&NBSP; HASHSET&NBSP;

public class Hashset<e> extends abstractset<e> implements Set<e>, Cloneable, java.io.Serializable {  Use HashMap key to save all elements in HashSet private transient hashmap<e,object> map;  A virtual object object is defined as the value of the HashMap private static final Object PRESENT = new Object ();  ...//Initialize HashSet, the underlying initializes a HASHMAP public HashSet () {map = new hashmap<e,object> (); }//created with the specified initialcapacity, Loadfactor HashSet//is actually created with the corresponding parameters HashMap public HashSet (int initialcapacity, float LOADF  Actor) {map = new hashmap<e,object> (initialcapacity, loadfactor);  } public HashSet (int initialcapacity) {map = new hashmap<e,object> (initialcapacity); } HashSet (int initialcapacity, float loadfactor, Boolean dummy) {map = new linkedhashmap<e,object> (Initialcapaci  Ty, loadfactor);  }//Call map KeySet to return all key public iterator<e> Iterator () {return Map.keyset (). Iterator (); }//Call the size () method of HashMap to return the number of Entry, and get the number of elements in the Set pubLIC int size () {return map.size (); }//Call HashMap's IsEmpty () to determine if the HashSet is empty,//When the HashMap is empty, the corresponding HashSet is also empty public boolean isEmpty () {return map.is  Empty ();  }//Call HashMap's containskey to determine whether all elements that contain the specified key//hashset are saved by the key of the HashMap, the public boolean contains (Object o) {  return Map.containskey (o);  }//Put the specified element into HashSet, that is, place the element as a key HashMap public boolean add (e e) {return Map.put (E, PRESENT) = = NULL; }//Call the Remove method of HashMap to delete the specified Entry, and then delete the corresponding element in the HashSet public boolean remove (Object o) {return map.remove (o) ==pres  ENT;  }//The Clear method of calling Map clears all Entry, and clears all elements in HashSet public void Clear () {map.clear (); }  ...  }

HASHSET&NBSP; HASHMAP&NBSP; HASHSET&NBSP; HASHMAP&NBSP; KEY&NBSP; to save , while   HASHMAP&NBSP; VALUE&NBSP; present OBJECT&NBSP; object.

Most of the methods of HashSet are implemented by invoking the HashMap method, so HashSet and HashMap Two sets are essentially the same in the implementation.

Reference: Crazy Java

Only analysis here ,LZ First look at the jdk Source code, there is a problem or can leave a message ...










Java container HashMap and HashSet learning

Related Article

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.