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 72 73 74 75 76 77 78
| /** * 设值 */ public V put(K key, V value) { return putVal(hash(key), key, value, false, true); }
/** * 如果存在此key的值,那就不设值用原值 */ public V putIfAbsent(K key, V value) { return putVal(hash(key), key, value, true, true); }
/** * 设值 * @param onlyIfAbsent 为true,就不改动原值 * @param evict 如果为false,则表处于创建模式 */ final V putVal(int hash, K key, V value, boolean onlyIfAbsent, boolean evict) { Node<K,V>[] tab; Node<K,V> p; int n, i; // 如果数组为null,也就是第一次put值,就resize进行扩容,这个方法后面再讲 if ((tab = table) == null || (n = tab.length) == 0) n = (tab = resize()).length; // 在数组中这个下标下如果这个链表为null,就根据传进的参数新建一个给它,也就是新建成链表头 if ((p = tab[i = (n - 1) & hash]) == null) tab[i] = newNode(hash, key, value, null); else { // 链表头不为null,e、k会当做循环这条链表的暂时值 Node<K,V> e; K k; // 如果刚好就是链表头,那就是e等于链表头 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) e = p; // 红黑树的部分看TreeNode类解析 else if (p instanceof TreeNode) e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); else { // 循环这条链表 for (int binCount = 0; ; ++binCount) { // next==null说明到链表尾了 if ((e = p.next) == null) { // 根据参数新建一个链表,作为链表尾 p.next = newNode(hash, key, value, null); // 如果链表长度不小于TREEIFY_THRESHOLD(8),就转换成红黑树 if (binCount >= TREEIFY_THRESHOLD - 1) // 如何转换的,这个后面再详解 treeifyBin(tab, hash); break; } // 如果在循环过程中发现存在此key,那就不用新建链表尾了 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) break; p = e; } } // 如果设值的key是已存在的 if (e != null) { V oldValue = e.value; // onlyIfAbsent为false,或者原值等于null,就设置成传入参数的value if (!onlyIfAbsent || oldValue == null) e.value = value; // 这里是空方法,在LinkedHashMap才会实现 afterNodeAccess(e); // 返回的旧值哦 return oldValue; } } ++modCount; // 超过最大容量,进行扩容 if (++size > threshold) resize(); // 这里是空方法,在LinkedHashMap才会实现 afterNodeInsertion(evict); return null; }
|