Java Collection Framework HashSet and HASHMAP source Analysis __java

Source: Internet
Author: User
Tags prev
Java Collection Framework HashSet and HASHMAP source Analysis General Introduction

The reason why we put HashSet and hashmap together, because they have the same implementation in Java, the former is only a layer of packaging, that is, hashset inside a HashMap (adapter mode). Therefore, this article will focus on the analysis of HashMap.


HASHMAP implements the map interface, allowing the null element to be placed, except that the class is not synchronized, the rest is roughly the same as the Hashtable, unlike TreeMap, the container does not guarantee the order of elements, as the container may be hashed to the elements as needed, and the order of the elements will be scattered again, So the order of the same hashmap at different times may be different.


Depending on how the conflict is handled, the hash table has two implementations, one open address (open addressing) and the other is the conflicting list (separate chaining with linked lists). The Java HashMap uses a conflict-linked list approach.

It is easy to see from the diagram above that if you choose the appropriate hash function, the put () and get () methods can be completed in constant time. However, when iterating over the HashMap, you need to traverse the entire table and the conflicting lists that follow. Therefore, it is not advisable to set the initial size of hashmap too large for the scenes with frequent iterations.


There are two parameters that can affect the performance of HashMap: initial capacity (inital capacity) and load factor (load factor). The initial capacity specifies the size of the initial table, and the load factor is used to specify the threshold for automatic expansion. When the number of entry exceeds Capacity*load_factor, the container will automatically expand and hash again. For scenes with more inserted elements, setting the initial capacity can reduce the number of hashes.


When putting a pair into hashmap or hashset, there are two methods that require special care: Hashcode () and Equals (). The Hashcode () method determines which bucket the object will be placed in, and when the hash value of multiple objects conflicts, the Equals () method determines whether the objects are "the same object". Therefore, if you want to put your custom objects into HashMap or hashset, you need to @override the hashcode () and Equals () methods.


Method Analysis

1.get ()

The Get (Object key) method returns the corresponding value based on the specified key value, which invokes the Getentry (object key) to obtain the corresponding entry, and then returns Entry.getvalue (). So Getentry () is the core of the algorithm.


Algorithm idea is first through the hash () function to get the corresponding bucket subscript, and then iterate through the conflict list, through the Key.equals (k) method to determine whether it is to find the entry.

Hash (k) & (Table.length-1) in the above figure is equivalent to hash (k)% Table.length, the reason is HashMap requirements table.length must be 2 of the index, so table.length-1 is the binary low total is 1, with the hash (k) phase of the hash value of all erase, the rest is the remainder.

Getentry () method
Final entry<k,v> getentry (Object key) {
......
int hash = (key = null)? 0:hash (key);
for (entry<k,v> e = table[hash& (table.length-1)];//get conflicting list
e!= null; E = e.next) {//iterate through each entry in the conflicting list sequentially
Object K;
Determine whether equality is based on the Equals () method
if (E.hash = hash &&
((k = e.key) = = Key | | (Key!= null && key.equals (k)))
return e;
}
return null;
}

2.put ()

The Put (K key, V value) method adds the specified key, value pair, to the map. The method first looks up the map to see if it contains the tuple, if it is already included, returns directly, the lookup process is similar to the Getentry () method, and if not found, passes the addentry (int hash, K key, V value, int Bucketindex) method inserts a new entry, the insertion method is the head interpolation.

AddEntry ()
void AddEntry (int hash, K key, V value, int bucketindex) {
if (size >= threshold) && (null!= table[bucketindex)) {
Resize (2 * table.length)//automatic expansion, and re-hashing
hash = (null!= key)? Hash (key): 0;
Bucketindex = hash & (table.length-1);//hash%table.length
}
Insert a new entry in the header of a conflict list
Entry<k,v> e = Table[bucketindex];
Table[bucketindex] = new entry<> (hash, key, value, E);
size++;
}


3.remove ()

The function of the Remove (object key) is to delete the corresponding entry of the key value, which is implemented in Removeentryforkey (object key). The Removeentryforkey () method first finds the corresponding entry of the key value, and then deletes the entry (the corresponding pointer to the linked list). The lookup process is similar to the getentry () procedure.

/removeentryforkey ()
Final entry<k,v> Removeentryforkey (Object key) {
......
int hash = (key = null)? 0:hash (key);
int i = indexfor (hash, table.length);//hash& (table.length-1)
Entry<k,v> prev = table[i];//get conflict list
entry<k,v> e = prev;
while (e!= null) {//Traverse conflict list
Entry<k,v> next = E.next;
Object K;
if (E.hash = hash &&
((k = e.key) = = Key | | (Key!= null && key.equals (k))) {//Find the entry to delete
modcount++; size--;
if (prev = = e) table[i] = next;//deleted is the first entry of the conflict list
else Prev.next = next;
return e;
}
prev = e; e = next;
}
return e;
}

HashSet

As mentioned earlier, HashSet is a simple wrapper for hashmap, and HashSet function calls are converted to the appropriate HashMap method, so the HashSet implementation is very simple, with less than 300 lines of code. Don't repeat it here.

HashSet is a simple package for hashmap.
public class Hashset<e>
{
......
Private transient hashmap<e,object> map;//hashset inside there is a HashMap
Dummy value to associate with a Object in the backing Map
private static final Object PRESENT = new Object ();
Public HashSet () {
Map = new hashmap<> ();
}
......
Public boolean Add (e e) {//simple method conversion
Return Map.put (E, PRESENT) ==null;
}
......
}

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.