Java 8 before ：

The underlying implementation is an array + Linked list , The main member variables are ： Storing data table array , Number of key value pairs size, Load factor loadFactor.

table Array for recording HashMap All data for , Each subscript of it corresponds to a linked list , All hash conflict data will be stored in the same linked list ,Entry

Is a node element of a linked list , Contains four member variables ： key key, value value, Execute pointer to next node next and Hash value of element hash.

stay HashMap The data in is in the form of key value pairs , Key corresponding hash Value will be used as its subscript in the array , If two elements key Of hash

Same value , Will send hash conflict , Is placed on a linked list in the same subscript , In order to HashMap As efficient as possible , Should make the hash Values are as scattered as possible .

HashMap The default initialization capacity is 16, Expansion capacity must be 2 Power of , The maximum capacity is 1<< 30 , The default load factor is 0.75.

1 put method ： Add element

① If key by null value , Direct deposit table[0].

② If key Not for null value , Calculate first key Corresponding hash value .

③ call indexFor Method basis key The hash value of and the length of the array i.

④ ergodic table[i] Corresponding linked list , If key Already exists , Update it value Value and return the old value value .

⑤ If key non-existent , I will modCount Value plus of 1, use addEntry Method to add a node , And return null value .

2 hash method ： Calculation element key Corresponding hash value

① handle String When data of type , Call the corresponding method directly to get the final hash value .

② When processing other types of data , Provide a relative HashMap The unique random value of an instance hashSeed As the initial quantity of calculation .

③ Perform exclusive or and unsigned move right operations to hash Values are more discrete , Reduce the probability of hash conflict .

3 indexFor method ： Calculate element subscript

Directly hash Values and array length - 1 Carry out and operate and return , Ensure that the calculated result will not exceed table Array length range .

4 resize method ： according to newCapacity To determine the new expansion threshold threshold

① If the current capacity has reached the maximum capacity , Set the threshold value to Integer Max of , After that, the expansion will not trigger again .

② Create a new capacity of newCapacity Of Entry array , And call transfer Method to transfer the elements of the old array to the new array .

③ Set threshold to （newCapacity And load factor loadFactor Product of ） and （ Maximum capacity + 1 ） The smaller of .

transfer： Transfer old array to new array

① Traverse all elements of the old array , call rehash Method to determine whether hash reconstruction is needed , Recalculate elements if necessary key Hash value of .

② call indexFor Method basis key The hash value of and the length of the array i, Transfer the elements of the old array to the new array .

5 get method ： according to key Get element's value value

① If key by null value , call getForNullKey method , If size by 0 Indicates that the list is empty , return null value . If size Not for

0, Indicates that there is a linked list , ergodic table[0] List of , If you find it key by null The node of returns its value value , Otherwise return null value .

② call getEntry method , If size by 0 Indicates that the list is empty , return null value . If size Not for 0, Calculate first key

Hash value of , Then traverse all nodes of the list , If the node's key Values and hash If the value is the same as the element to be found, it will be returned Entry node .

③ If the corresponding Entry node , use getValue Method to get its value Value and return , Otherwise return null value .

Java 8 after ：

Using arrays + Linked list / The form of Mangrove ,table Array element data type changed to Entry Static implementation class of Node.

1 put method ： Add element

① call putVal Method add element .

② If table Expand when empty or no element , Otherwise calculate element subscript position , If it doesn't exist, create a new node to store .

③ If the hash Values and key Same value , Direct update value value .

④ If the first node is TreeNode type , call putTreeVal

Method to add a tree node , Compare the size of the inserted node and the current node each time , When the node to be inserted is small, search to the left subtree , Otherwise, search right subtree , Two methods are executed after finding the empty space ：balanceInsert

method , On the one hand, insert the node into the red black tree , On the one hand, adjust and balance the red and black trees .moveRootToFront method , Due to the balance adjustment of red and black trees

root Nodes may change ,table The node recorded in is no longer the root node , Root node needs to be reset .

⑤ If it is a linked list node , Just traverse the list , according to hash Values and key

Value judgment is repeated , Decide whether to update the value or add a new node . If you traverse to the end of the list , Add linked list element , If the tree building threshold is reached , You also need to call treeifyBin Method to reconstruct the linked list into a red black tree .

⑥ After storing elements , take modCount Value plus 1, If the number of nodes + 1 Greater than capacity expansion threshold , Capacity expansion is also needed .

2 get method ： according to key Get element's value value

① call getNode Method acquisition Node node , If not null Value returns Node Node's value value , Otherwise return null.

② If the array is not empty , Compare the first node with the hash Values and key value , If both are the same, return directly .

③ If the second node is TreeNode Nodes call getTreeNode Method to find , Otherwise, traverse the list according to hash Values and key

Value to find , Return if not found null.

3 hash method ： Calculation element key Corresponding hash value

Java 8 It's a lot easier , If key Will not be empty key Of hashCode()

High and low return value 16 Bit for exclusive or operation , This is mainly to let as many bits as possible participate in the operation , Let the 0 and 1 More evenly distributed , So as to reduce the probability of hash conflict .

4 resize method ： Expand array

Re planning length and thresholds , If the length changes , Some data nodes also need to be rearranged .

Re planning length

① If size Capacity expansion threshold exceeded , hold table Increase capacity to previous 2 times .

② If new table Capacity less than default initialization capacity 16, Then table Capacity reset to 16.

③ If new table Capacity is greater than or equal to the maximum capacity , Then set the threshold value to Integer Max of , also return Termination of capacity expansion , because size

It is impossible to exceed this value, so the capacity expansion will not occur later .

Rearrange data nodes

① If the node is null Value is not processed .

② If the node is not null Value and no next node , Then recalculate its hash value and store the new table In array .

③ If the node is TreeNode node , Then call split Method , This method is used to adjust the red black tree , If it is too small, it will degrade back to the linked list .

④ If the node is a linked list node , The linked list needs to be split into hashCode() Return the list whose value exceeds the old capacity and the list whose value does not exceed the capacity . about hash & oldCap == 0

The part of does not need to be processed , On the contrary, it needs to be placed in a new subscript position , New subscript = Old subscript + Old capacity .

supplement ： Mangrove

Red black tree is a self balanced binary search tree .

characteristic ：

Each node of the red black tree can only be red or black , The root node is black , Every leaf node is black , If a leaf node is red , Its child nodes must be black , All paths from a node to its leaf nodes contain the same number of black nodes .

Sinistral ： Yes a Node left turn , Refer to general a Right node of node as a Parent node of , soon a Become a left node .

Dextral ： Yes a Node rotate right , Refer to general a Left node of node as a Parent node of , soon a Become a right node .

add to

The addition of red black tree is divided into 3 step ：① Consider red black tree as a binary search tree , And insert the new node with the insertion rule of binary tree .② Set the inserted node to red or black .③

Through left , Right handed or discolored , Make it a red black tree again .

According to the parent node of the inserted node , Inserts can be divided into 3 Case handling ：

* The inserted node is the root node , Paint it black directly .

* The parent of the inserted node is black , No processing , Red black tree after node insertion .

* The parent of the inserted node is red , There must be non empty grandfather nodes , Further divided into three situations ：

* Uncle node is red , Set parent node to black , Uncle node set to black , Grandfather node set to red , Make grandfather node the current node .

* Uncle node is black and current node is right node , Set the parent node as the current node , Rotate left with the new node as the fulcrum .

* Uncle node is black and current node is left , Set the parent node to black , Grandfather node set to red , Rotate right with grandfather node as pivot .

delete

The addition of red black tree is divided into 3 step ：① Consider red black tree as a binary search tree , And delete the new node with the delete rule of binary tree .② Through left , Right handed or discolored , Make it a red black tree again .

According to the deleted node , Delete can be divided into 3 Case handling ：

* The deleted node has no children , Delete it directly .

* The deleted node has only one child , Delete the node directly , And replace its location with its unique child node .

* The inserted node has two children , Find the replacement node of this node first , Then copy the value of the replacement node to the node , Delete replacement node .

Through left , To turn right or change color to make a redwood . If the current node's child nodes are one red one black , Set the node to black directly . If the current node's children are all black , And the current node is the root node , Do not handle . If the current node's children are all black and the current node is not the root node , It can be divided into the following situations ：

* The sibling of the current node is red , Set the sibling of the current node to black , Set parent node to red , Rotate left to parent node , Reset the sibling of the current node .

* The sibling of the current node is black , The two child nodes of brother nodes are also black , Set the sibling of the current node to red , Make the parent of the current node the new node .

* The sibling of the current node is black , Brother node's left node is red, right node is black , Set the left child of the current node to black , Set brother node to red , Right turn brother node , Reset sibling .

*

The sibling of the current node is black , The right node of brother node is red , Assign parent node of current node to sibling node , Set parent node to black , Set the right child of the sibling node to black , Rotate left to parent node , Set current node as root node .

Technology

- Java426 articles
- Python242 articles
- Vue127 articles
- Linux119 articles
- MySQL100 articles
- javascript77 articles
- SpringBoot72 articles
- C++68 articles
- more...

Daily Recommendation

©2019-2020 Toolsou All rights reserved,

html Writing about cherry trees , Writing about cherry trees It's unexpected Python Cherry tree （turtle The gorgeous style of Library ） Browser kernel （ understand ）HashMap Explain in detail java Four functional interfaces （ a key , simple ）os Simple use of module Some East 14 Pay change 16 salary , Sincerity or routine ?