1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| /** * @param hash hash值 * @param key key * @param value value * @param onlyIfAbsent 如果是true则不改变已有值 * @param evict 如果是false则为创建模式 * @return 返回改变之前的值 */ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; // 局部变量table Node<K,V> p; // 原始node int n; // table长度 int i; // node在table中的位置
// 判断table是否等于null或者为空 // 如果为空则进行扩容 if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length;
// 对hash值进行取模得到i // 当hash为2的次幂,x % hash == x & (hash - 1) // 位运算效率远远高于取模运算,所以这里使用位运算代替取模 if ((p = tab[i = (n - 1) & hash]) == null) // 如果没有原始值,则new一个新node放入table tab[i] = newNode(hash, key, value, null); else { Node<K,V> e; // 已存在节点e K k; // 已存在节点的key if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) // 如果hash值相等并且key相等 e = p; else if (p instanceof TreeNode) // 如果p是一个红黑树则放入树中 e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else { // hash冲突情况,遍历链表 for (int binCount = 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; } // 如果hash值相等并且key相等 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; // 设置p为当前链表节点 p = e; } } // 判断是否存在旧值 if (e != null) { // existing mapping for key V oldValue = e.value; // 改变旧值 if (!onlyIfAbsent || oldValue == null) e.value = value; afterNodeAccess(e); // 返回旧值 return oldValue; } } ++modCount; // 如果长度大于阈值则进行扩容 if (++size > threshold) resize(); afterNodeInsertion(evict); return null; }
|