EachAlgorithmTo solve some problems, the hash algorithm is no exception. The most common applications of the hash algorithm are: hash tables for quick search; consistent hash algorithms, cache systems; Sha and so on, which are used for encryption.
Applications for quick search are everywhere. Hashmap is a classic application example in Java. Hashmap itself is implemented using a hash table and a linked list. By performing hash on the key and secondary hash, the obtained result is the same as the hash table length-1 and the bitwise AND (&) operation is performed to determine the position (INDEX) of the key in the hash table ). Of course, there are deep considerations for secondary hash during the implementation of hashmap. The implementation of hashmap is of high quality.Article. Deepen your understanding of the hash algorithm in search applications.
The beauty of access-hashmap principle and practice hashmap is a very common data structure. As an application developer, a deeper understanding of its principles and implementations will facilitate more efficient data access. The JDK version used in this article is 1.5. Using hashmap in objective Java, we believe that, in 99% cases, when you overwrite the equals method, you must overwrite the hashcode method. By default, the two will adopt the "native" implementation method of the object, that is, view plaincopy to clipboardprint? Protected native int hashcode (); Public Boolean equals (Object OBJ) {return (this = OBJ);} the definition of the hashcode method uses the native keyword, it indicates that it is implemented by C or C ++ in a lower-layer mode. You can think that it returns the memory address of the object. The default equals considers that, they are considered equal only when the two reference the same object. If you only overwrite equals () without redefining hashcode (), when reading hashmap, unless you use an object that is identical to the one you used to reference when saving it as the key value, otherwise, you will not get the value corresponding to the key. On the other hand, you should try to avoid using a "variable" class as the hashmap key. If you save an object as a key value in hashmap and change its state, hashmap will produce confusion, the value you saved may be lost (even though the traversal set can be found ). Hashmap Access Mechanism hashmap is actually a combination of arrays and linked lists. It uses arrays to simulate buckets (similar to bucket sort) to quickly access keys of different hashcodes. For different keys with the same hashcode, then, call the equals method to extract the value corresponding to the key from the list. In Java, hashmap Initialization is mainly to assign values to the initialcapacity and loadfactor attributes. The former indicates the length of the key space used in hashmap to distinguish different hash values. The latter specifies the number of elements in the hashmap when the number of elements exceeds ,. By default, initialcapacity is 16 and loadfactor is 0.75. It indicates that hashmap can store 16 different hashcodes at the beginning. When it is filled with 12th hashcodes, hashmap automatically expands the length of its key space to 32, and so on. This can be seen from the source code: View plaincopy to clipboardprint? Void addentry (INT hash, K key, V value, int bucketindex) {entry <K, V> E = table [bucketindex]; Table [bucketindex] = new entry <K, v> (hash, key, value, e); If (size ++> = threshold) resize (2 * table. length);} and every time a hashmap is scaled up, the storage location of each element inside will change (because the final position of the element is its hashcode modulo the length of the key space ), therefore, the resize method calls the transfer function to re-allocate internal elements. This process becomes rehash, which consumes a lot of performance. Therefore, when the number of predictable elements is met, generally, you should avoid using the default initialcapacity, but specify a value for it through the constructor. For example, we may want to cache the 1000 records obtained from database queries with a specific field (such as ID) as the key in hashmap. To improve efficiency and avoid rehash, you can directly specify initialcapacity as 2048. Another noteworthy point is that the key space length of hashmap must be 2 to the Npower, which can be seen from the source code: View plaincopy to clipboardprint? Int capacity = 1; while (capacity <initialcapacity) capacity <= 1; even if the initialcapacity specified in the constructor is not the number of workers of 2, capacity is still assigned to the Npower of 2. Why should Sun Microsystem engineers set the length of the hashmap key space to the N power of 2? Refer to R. w. floyed provides three criteria for measuring the hash concept: A good hash algorithm should calculate very quickly, and a good hash algorithm should be a conflict minimization. If there is a conflict, it should be balanced. To save the hashcode of each element to the key array whose length is length, the modulo mode is generally used, that is, Index = hashcode % length. Inevitably, the hashcode of multiple different objects is arranged in the same location. This is what we call "conflict ". If we only consider elemental homogenization and conflict minimization, it seems that length should be taken as a prime number (although there is no obvious theory to support this, mathematicians come to the conclusion through a large number of practices, the result of modulo operation on prime numbers is more independent than other numbers ). To this end, Craig larman and Rhett Guthrie attacked this in Java into mence. Bruce Eckel (author of thinking in Java) made a special interview with Java. util. joshua Bloch, author of hashmap, and posted the reason he used this design online (http://www.roseindia.net/javatutorials/javahashmap.shtml ). The reason for the above design is that the efficiency of the modulo operation in most languages including Java is very low, and when the divisor is 2, the modulo operation degrades to the simplest bit operation, and the efficiency is significantly improved (according to the data given by Bruce Eckel, it can be improved by about 5 ~ 8 times ). Let's see how JDK implements: View plaincopy to clipboardprint? Static int indexfor (int h, int length) {return H & (length-1);} when the key space length is 2 to the Npower, indexes of elements whose hashcode is h can be replaced by clumsy modulo operations by simple operations! Assume that the hashcode of an object is 35 (the binary value is 100011), and hashmap uses the default initialcapacity (16), then the indexfor calculation result will be 100011 & 1111 = 11, that is, decimal 3, is it exactly 35 mod 16. The above method has a problem, that is, its calculation result is only determined by the low level of the object hashcode, and the high level is all blocked. For example, 19 (10011), 35 (100011) and 67 (1000011) have the same results. To address this problem, Joshua Bloch adopts the "Defensive Programming" solution to perform secondary hash before using the hashcode of each object. For details, refer to the source code in JDK: View plaincopy to clipboardprint? Static int Hash (Object X) {int H = x. hashcode (); H ++ = ~ (H <9); H ^ = (h> 14); H + = (H <4); H ^ = (H >>> 10 ); return h;} the main purpose of using this rotating hash function is to make full use of the high information of the original hashcode, and take into account the computing efficiency and the characteristics of data statistics, its principle is beyond the scope of this article. Another effective way to speed up hash efficiency is to write a good hashcode for custom objects. The implementation of string adopts the following calculation method: View plaincopy to clipboardprint? For (INT I = 0; I <Len; I ++) {H = 31 * H + val [Off ++];} hash = h; this hashcode calculation method may first appear in Brian W. kernighan and Dennis M. ritchie's "The C programming language" is considered to be the most cost-effective algorithm (also known as the times33 algorithm, because the multiplier constant in C is 33 and changed to 31 in Java). In fact, most objects, including list, use this method to calculate the hash value. Another special hash algorithm is called bloom filter. At the cost of precision, it is used to save a lot of storage space. It is often used to judge whether the user name is repeated or whether it is on the blacklist.