openjdk 17.0.11 2024-04-16 LTS OpenJDK Runtime Environment Corretto-17.0.11.9.1 (build 17.0.11+9-LTS) OpenJDK 64-Bit Server VM Corretto-17.0.11.9.1 (build 17.0.11+9-LTS, mixed mode, sharing)
插入元素
调用 put 方法插入一个键值对,流程为:
调用 putVal 方法
1 2 3
public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }
如果为空表,则进行初始化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
/** * Implements Map.put and related methods. * * @param hash hash for key * @param key the key * @param value the value to put * @param onlyIfAbsent if true, don't change existing value * @param evict if false, the table is in creation mode. * @return previous value, or null if none */ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; if ((tab = table) == null || (n = tab.length) == 0) // 如果当前表为空表,初始化表。 n = (tab = resize()).length; ... }
如果当前的哈希桶(桶数组)为空,直接插入
1 2 3 4 5 6 7 8
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { ... // 当前桶数组为空。 if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); ... }
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { ... if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); else { ... else { // 遍历链表节点 for (intbinCount=0; ; ++binCount) { // 在尾部插入新键值对 if ((e = p.next) == null) { p.next = newNode(hash, key, value, null); // 链表节点超过阈值,进行树化 if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st treeifyBin(tab, hash); break; } // 存在重复节点 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } ... } ... }
如果表中元素数量大于阈值,则进行扩容。
1 2 3 4 5 6 7 8 9 10
final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { ... ++modCount; // 元素数量大于阈值进行扩容 if (++size > threshold) resize(); afterNodeInsertion(evict); returnnull; }