concept

  • HasnMap is implemented based on the Map interface. Elements are stored as key-value pairs, and both keys and values can be null becauseThe key cannot be repeated, so only one key can be null
  • HaasnMap isDisorder without repetitionAnd HashMap isThread insecuritythe

Representation of HashMap for different JVM versions

  • JDK7
    • The data structure of HashMap is:Array + linked list
  • JDK8
    • The data structure of HashMap is:Array + linked list + red-black tree

Advantages of storage

  • Array features: query efficiencyhigh, insert and delete efficiencylow
  • Linked list features: query efficiencylow, insert and delete efficiencyhigh
  • Use array plus underneath HasnMap(Linked list or red-black tree)The structure of the perfect array and linked list to solve the problem, so that the query and insert, delete efficiencyhigh
  • The HashMap hash table isLazy loading mechanism, is created on the first put

Procedure for storing elements in a HashMap

  • Encapsulate k and V into Node objects
  • Call k’s hasnCode() method to retrieve the hash value; The subscript of the element store is obtained by modulating the hashcode value and the array length
  • There are two cases
    • There’s no element in the subscript position, just put the element square in
    • Determine whether the elements at that position are equal to the current element using equals (the default is to compare the addresses of two objects). If they are equal, they are overwritten. If they are not, the element is stored in a list structure under the original element (if a list already exists, it is inserted at the end of the list). Each element node has a next attribute pointing to the next node, which changes from an array structure to an array + list. Because too many elements in the linked list will affect the search efficiency, so when the number of elements in the linked list reaches8When the number of nodes in the red-black tree is less than6The reason is that red black trees are balanced binary trees, which have better lookup performance than chat tables

Implementation of HashMap values

  • K’s hashCode() method is called to derive the hash value, which is converted to the array’s subscript using the hash algorithm
  • After converting the hash value to the array subscript, locate the subscript position through the array. If there is nothing in the position, the range is null. If the position has a singly linked list, then take the parameters K and singly linked list of every node on the K equals comparison, if all equals returns false, it returns null, if there is a node parameters K and K by equals returns true, Then the value of this object is the value to be obtained

capacity

  • There are two important parameters in a HashMap, the initial capacity and the load factor. When a HashMap is first initialized, using the default constructor, an empty table is returned and thershold is0, so the default value for the first expansion will be16, the default load factor is0.75, the array capacity is multiplied by the load factor to get a value. Once the number of elements stored in the array exceeds this value, the rehash method will be called to increase the array capacity to twice the original value, and the threshold will also become twice the original value
  • During capacity expansion, a new array is generated, and all the original data needs to be recalculated and reassigned to the new array. Therefore, capacity expansion consumes a lot of performance. Therefore, if you know the amount of data to be stored, you can specify a large amount of data at the time of creation
  • When the HashMap is initialized and inserted for the first time, resize expansion and data insertion will take place first. Then, when the number of inserted data reaches the threshold, resize will take place. In this case, data insertion and data resize will take place first

Is a capacity expansion in a HashMap done before or after element insertion

  • inJDK1.7In is the element insertbeforeFor expansion, inJDK1.8Is to add elements firstafterThen determine whether to expand the capacity

Will storage elements be expanded when they exceed the threshold

  • inJDK1.7The capacity expansion is performed only when the number of stored elements exceeds the threshold and the current storage location is not nullJDK1.8Capacity expansion will be performed in

HashMap is different from HashTable

  • The thread in
    • HashMap is thread-safe, HashTable is thread-safe. The implementation methods of Hashtable all add the synchronized keyword to ensure thread synchronization, so the performance of HashMap is relatively higher. We recommend using HashMap if there is no special requirement in ordinary use, but need to use HashMap in multi-threaded environmentCollections.synchronizedMap()Method to get a thread-safe collection
  • The key of a HashMap can be null, but the key of a HashTable cannot be null
  • HashMap is an implementation of the Map interface. HashTable implements both the Map interface and the Dictionary abstract class
  • The initial capacity of a HashMap is16, the initial capacity of Hashtable is11, the default fill factor for both is0.75When HashMap is expanded, the current capacity is doubled, namely:capacity * 2When Hashtable is expanded, the capacity is doubled +1.capacity * 2+1

How to generate hashcode in HashMap

  • Call the hashCode method of the object key, and perform some right shifts and xor operations on the hashCode method (involving both the high and low parts of the hashCode); Right shift and xOR operations can make hashMap hashing stronger and improve the efficiency of hashMap get methods

Why HashCode

  • HashCode exists mainly for lookups. HashCode is used to determine the storage address of an object in a hash storage structure (using HashCode to represent the object’s position in the hash table), One of the main reasons hashCode exists is because it is used in a HashMap (a HashSet is actually a HashMap)fastBecause what he used wasHash table, generate array subscript based on the hashcode value of key (search by memory address directly, do not need to judge, but need more memory, equivalent to space for time)

Equals method and HashCode

Summary:

  • If you override equals(Object obj), it is necessary to override the hashCode() method
  • If equals(Object obj) returns true, it is necessary that hashCode() also return the same int
  • HashCode () does not necessarily return different ints if equals(Object obj) returns false
  • If two objects hashCode() return the same int, equals(Object obj) does not necessarily return true
  • If two objects hashCode() return different ints, equals(Object obj) must return false
  • If the same object is already stored in the collection during execution, you cannot modify the information that affects the hashCode value, otherwise it will cause memory leaks

What if the key is null

  • When a key is null, it is placed at the zero position of the hashMap (that is, the hashCode of the key is 0 and the subscript of the array length mod is 0), and there is no linked list
  • In the HashMap source code for the put method to do null processing, key is null judgment after enteringputForNullKey(V value)In this method, the for loop is inTalbe [0]If found, reassign value to the element’s value and return the original value. If not, add the element to the head of talbe[0]
/** * public V put(K key, V value) {if (table == EMPTY_TABLE) {inflateTable(threshold); } putForNullKey(value) if (key == null) return putForNullKey(value); int hash = hash(key); int i = indexFor(hash, table.length); for (Entry<K,V> e = table[i]; e ! = null; e = e.next) { Object k; if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(hash, key, value, i); return null; } /** * Offloaded version of put for null keys */ private V putForNullKey(V value) { e = table[0]; e ! = null; e = e.next) { if (e.key == null) { V oldValue = e.value; e.value = value; e.recordAccess(this); return oldValue; } } modCount++; addEntry(0, null, value, 0); return null; }Copy the code