There are arrays and linked lists in the data structure to achieve the storage, but the array storage interval is continuous, easy to address, insert and delete difficult, and the list of the space is discrete, so addressing difficulties, insert and delete easy.
Therefore, combining the advantages of both, we can design a data structure-a hash table (hash table), it is easy to address, insert and delete. In Java, the implementation of the hash table is mainly HashMap, it can be said that HashMap is one of the most used classes in Java development.
The bottom of the HashMap is actually an array of linked lists, and the code is
Transient entry[] table;
The table here is actually a list of arrays, because our data is two yuan, so HashMap defines an internal class entry, which contains the key and value two properties. Such a one-dimensional linear array can store two values. At the same time entry is a linked list, so there is also a entry next property, which points to the next node.
When storing put:
First calculate the hash of the key, and then use Table[hash] to get that list, and then traverse the list, if there is a key in the list and this key is satisfied equals, then the value is replaced, if not, then inserted into the tail of the list.
int h == table[h];
for null; E = e.next) { Object k; // replace the key with the new value if it already exists in the linked list if (E.hash = = Hash && (k = e.key) = = Key | | Key.equals (k))) { = e.value; = value; E.recordaccess (this); return oldValue; } }
At GET, it is also the same way to get that list entry E; and then traverse the list to take out the elements
for (entry<k,v> e = table[indexfor (hash, table.length)]; NULL ; = e.next) { Object k; if (E.hash = = Hash && (k = e.key) = = Key | | Key.equals (k))) return e.value; } return null;
HashMap Optimization of performance:
HashMap performance optimization, mainly in the reduction of hash conflict (different keys to calculate the same hash), because the more hash conflict, from the list of the time required to address the longer.
1. Reduce the hash conflict by calculating the hash value:
This hash method effectively reduces the hash conflict: (specifically I do not understand!) Reference http://zhangshixi.iteye.com/blog/672697)
Static int hash (int h) { ^= (H >>>) ^ (h >>>n); return H ^ (H >>> 7) ^ (H >>> 4); } Static int indexfor (intint length) { return H & (length-1 ); }
I wrote a very simple way to calculate the hash value, barely able to use:
Math.Abs (o==null? 0:o.hashcode ())% length
2. Automatic expansion
When there are more and more elements in the HashMap, the probability of hash collisions becomes higher, because the length of the array is fixed. Therefore, the expansion of the array is required at this point.
Array expansion occurs when the number of elements in HashMap exceeds the array size *loadfactor (the default value of 0.75). At this point, you need to create a new table to map the original table to the new table.
When expanding, iterate through each element, recalculate its hash value, and then add it to the new table.
In general, the size of the expansion array is twice times the size of the original array. This is a very performance-intensive operation, so if we've already predicted the number of elements in the HashMap, setting the initial capacity ahead of time will greatly improve its performance.
I put my source on the GitHub, welcome to download communication.
http://pan.baidu.com/s/1dFj2405
Https://github.com/xcr1234/my-java
Attached to the performance test results of their own implementation, barely acceptable
There must be a lot of inadequacies in this blog post and the code, and ask the great God to point it out! or fork My Code and make valuable suggestions, thank you!
Java--hashmap implementation of the principle of self-realization of the simple HashMap