Overview
HashMap is a K/V key-value pair data structure with fast search and good insertion and deletion performance. It is implemented based on the Map interface of the hash table. It is one of the commonly used Java collections and is non-thread safe.
Data Structure
JDK1.7
The bottom layer uses array (Entry<K, V>) + linked list. Use size & hash to find the array index position. If there is a conflict, use the zipper method to resolve the conflict.
Open hashing: Simply put, it combines a linked list and an array. That is to say, create a linked list array, and each cell in the array is a linked list. If a hash conflict is encountered, the conflicting value is added to the linked list. As shown below
JDK1.8
The underlying initial data structure still uses array + linked list. When the length of a bucket linked list is greater than 8, and the array length is greater than or equal to 64, if so, the red-black tree conversion operation is performed. As shown below
Source code analysis
1.Let’s analyze it first from the source code of JDK1.7. The main core method in this version is the put method. During the put process, the HashMap will be expanded. The default size is 16. The expansion factor is 0.75, that is, when the length of the HashMap reaches 12 The size will be expanded to 2 times the original size. We will explain this method in detail. The source code comments are as follows.
code analysis
1 |
|
2.For JDK1.8 and later, the underlying structure of HashMap has changed to adopt the structure of array + linked list + red-black tree. Why is there such a modification? When there are a large number of elements in the HashMap stored in the same bucket, there is a long linked list under the bucket. At this time, the HashMap is equivalent to a singly linked list. If the singly linked list has n elements, the time complexity of traversal is O(n), completely losing its advantage. Because there will be a process of converting a linked list to a red-black tree and a red-black tree to a linked list,so we need to analyze the putVal and removeNode methods for the JDK1.8 code. The code and some comments are as follows
1 |
|
Summarize
1.The default initial length of HashMap’s hash bucket Length is 16, and the default load factor loadFactor is 0.75. The threshold is the number of Node nodes with the maximum amount of data that HashMap can accommodate, threshold=Length*loadFactor
2.When the number of elements stored in HashMap exceeds the threshold, the reseize expansion operation will be performed. The expanded array capacity will be twice the previous one; but expansion is a particularly performance-consuming operation, so when we use HashMap When , you can estimate the size of the Map and specify a rough value during initialization, which can reduce the number of frequent expansions of the Map.
3.The size of the HashMap hash bucket is a power of 2. Each expansion is also 2 times. The purpose is to spread the elements evenly in the hashmap and reduce hash collisions.
4.JDK1.8 introduces red-black tree operation. When the length of the linked list reaches 8 and the number of HashMap is greater than or equal to 64, it will be converted into a red-black tree.Convert the red-black tree to a linked list 1) Delete the node that is the root node of the red-black tree or the left or right node of the root 2) Recalculate the number inside the bucket <= 6 during expansion