HashMap 源码
HashMap源码
解释了大部分代码, 还剩下一小部分,尽快补上
1 package java.util; 2 3 import java.io.IOException; 4 import java.io.InvalidObjectException; 5 import java.io.Serializable; 6 import java.lang.reflect.ParameterizedType; 7 import java.lang.reflect.Type; 8 import java.util.function.BiConsumer; 9 import java.util.function.BiFunction; 10 import java.util.function.Consumer; 11 import java.util.function.Function; 12 import sun.misc.SharedSecrets; 13 14 /** 15 * 基于Hash表的Map界面的实现。 16 * 此实现提供了所有可选的映射操作,并允许NULL value和NULL key。 17 * (HASMAP类大致等同于Hash表,除了它是不同步的,并且允许空值。) 18 * 这个类不保证映射的顺序;特别是,它不保证顺序将随时间保持不变。 19 * 20 * 这个实现为基本操作(get和put)提供了恒定时间的性能,假设Hash函数将元素适当地分散到桶中。 21 * 对集合视图的迭代需要与HashMap实例的“容量”(桶的数量)及其大小(key-value映射的数量)成比例的时间。 22 * 因此,如果迭代性能很重要,那么不要将初始容量设置得太高(或负载系数太低)非常重要。 23 * 24 * HASMAP的一个实例有两个参数影响其性能:初始容量和负载因子。 25 * 容量是Hash表中的桶数,初始容量只是创建Hash表时的容量。 26 * 负载因子是在容量自动增加之前允许Hash表的满度的量度。 27 * 当Hash表中的条目的数量超过负载系数和当前容量的乘积时,对Hash表进行重新Hash(即,重建内部数据结构),使得Hash表具有大约两倍于桶的数量。 28 * 29 * 作为一般规则,默认负载因子(0.75)在时间和空间成本之间提供了很好的折衷。 30 * 较高的值减少了空间开销,但是增加了查找成本(反映在HashMap类的大多数操作中,包括get和put)。 31 * 在设置映射的初始容量时,应该考虑映射中的预期条目数量及其负载因子,以便最小化重散列操作的数量。 32 * 如果初始容量大于最大条目数除以负载因子,则不会发生重新散列操作。 33 * 34 * 如果要在HashMap实例中存储许多映射,则创建具有足够大容量的映射将允许更有效地存储映射,而不是让它根据需要执行自动重散列来增长表。 35 * 注意,使用同一个HASCODE()的多个key是降低任何Hash表性能的可靠方法。 36 * 为了改善影响,当key可比较时,该类可以使用key之间的比较顺序来帮助断开关系。 37 * 38 * 请注意,此实现不同步。 39 * 如果多个线程同时访问Hash映射,并且至少一个线程在结构上修改映射,则必须在外部对其进行同步。 40 * (结构修改是添加或删除一个或多个映射的任何操作;仅仅更改与实例已经包含的key相关联的value不是结构修改。) 41 * 这通常是通过对一些自然封装Map的对象进行同步来实现的。 42 * 43 * 如果不存在这样的对象,则该映射应该使用Collections.synchronizedMap方法“包装”。 44 * 最好在创建时这样做,以防止意外地异步访问映射:Map m=Collections.synchronizedMap(new HashMap(...)); 45 * 46 * 所有此类的“集合视图方法”返回的迭代器都是fail-fast的:如果映射在创建迭代器之后的任何时间以除了通过迭代器自己的remove方法之外的任何方式在结构上被修改,则迭代器将抛出ConcurrentModificationException。 47 * 因此,在面临并发修改时,迭代器会快速而干净地失败,而不会在未来不确定的时间冒任意、非确定性行为的风险。 48 * 49 * 注意,迭代器的fail-fast行为不能得到保证,因为一般来说,在存在非同步的并发修改的情况下,不可能做出任何硬保证。 50 * 故障快速迭代器在尽力的基础上抛出CONTRONUTION修改异常。 51 * 因此,编写依赖于此异常的程序来确保其正确性是错误的:迭代器的快速失败行为应该只用于检测bug。 52 * 53 */ 54 public class HashMap<K,V> extends AbstractMap<K,V> 55 implements Map<K,V>, Cloneable, Serializable { 56 57 private static final long serialVersionUID = 362498820763181265L; 58 59 /** 60 * * 执行的笔记。 61 * 62 * 这个映射通常作为 链表(用桶装)哈希表,但是当链表太大时,它们被转换为树箱,每个树箱的结构与java.util.TreeMap中的类似。 63 * 大多数方法尝试使用正常的容器,但在适用时中继到树型方法(简单地通过检查节点的实例)。 64 * 可以像其他任何一样遍历和使用树状物的容器,但是当人口过密时,还支持更快的查找。 65 * 然而,由于正常使用的绝大多数箱子都不是过度填充的,因此在表方法过程中,检查树箱是否存在可能会延迟。 66 * 67 * 树箱(即,其元素都是TreeNode的箱)主要由hashCode排序,但是在联结的情况下,如果两个元素具有相同的“C类实现Comparable<C>”,则键入它们的 compareTo 方法来排序。 68 * (我们通过反射来保守地检查泛型类型,以验证这一点——参见方法SababeCabaseFor)。 69 * 当键具有不同的散列或者可排序时,树箱增加的复杂性对于提供最差情况O(log n)操作是值得的,因此,在hashCode()方法返回分布较差的值的意外或恶意使用下,性能优雅地降低,就像我们LL是许多密钥共享Hash码的那些,只要它们是可比的。 70 * (如果这两种方法都不适用,我们可能会浪费时间和空间的两倍,而不采取任何预防措施。 71 * 但是,唯一已知的案例源于用户编程的不良行为,这些做法已经非常缓慢,这几乎没有什么区别。 72 * 73 * 因为TreeNode的大小大约是常规节点的两倍,因此我们只有在容器中包含足够的节点来保证使用时才使用它们(参见TREEIFY_THRESHOLD)。 74 * 当它们变得太小(由于移除或调整大小)时,它们被转换回普通容器。 75 * 在使用分布良好的用户哈希代码的情况下,很少使用树箱。 76 * 77 * 理想情况下,在随机hashCodes下,容器中的节点的频率遵循泊松分布(http://en.wikipedia.org/wiki/Poisson_.),对于0.75的默认大小调整阈值,平均参数约为0.5,尽管由于大小调整粒度而存在很大的差异。 78 * 忽略方差,列表大小k的期望发生是(exp(-0.5) * pow(0.5, k) / factorial(k)). 79 * 第一个值是: 80 * 0: 0.60653066 81 * 1: 0.30326533 82 * 2: 0.07581633 83 * 3: 0.01263606 84 * 4: 0.00157952 85 * 5: 0.00015795 86 * 6: 0.00001316 87 * 7: 0.00000094 88 * 8: 0.00000006 89 * 更多:小于千万分之一 90 * 91 * 树箱的根通常是它的第一个节点。 92 * 但是,有时候(当前仅在Iterator.remove时),根可能在其他地方,但是可以在父链接之后恢复(方法TreeNode.root())。 93 * 94 * 所有适用的内部方法都接受哈希代码作为参数(通常由公共方法提供),允许它们彼此调用而不重新计算用户哈希代码。 95 * 大多数内部方法还接受“tab”参数,通常是当前表,但在调整大小或转换时可能是新表或旧表。 96 * 97 * 在桶树化,分裂,或 反树化,我们把他们放在同一个相对访问/遍历顺序(即场节点。下)更好的保存的地方,并稍微简化的分裂和遍历调用Iterator.remove操作。 98 * 当在插入中使用比较器时,为了在重新平衡中保持总排序(或在这里需要的接近),我们将类和身份HashCodes作为连接断路器进行比较。 99 * 100 * 由于子类LinkedHashMap的存在,普通VS树模式之间的使用和转换是复杂的。 101 * 见下面的钩子被调用方法定义的插入后,去除和访问,让LinkedHashMap的内部或保持独立的力学。 102 * (这也要求将一个MAP实例传递给可能创建新节点的一些实用工具方法。) 103 * 104 * 类似SSA的编码风格的并发编程有助于避免所有扭曲的指针操作中的混叠错误。 105 * 106 */ 107 108 109 /** 110 * 默认初始容量。必须是2的幂 111 */ 112 113 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 114 115 /** 116 * 最大容量,如果一个更高的值隐式地由任何一个带有参数的构造函数指定。必须是2的30次幂 117 */ 118 static final int MAXIMUM_CAPACITY = 1 << 30; 119 120 /** 121 * 在构造函数中没有指定时使用的负载因子。 122 */ 123 static final float DEFAULT_LOAD_FACTOR = 0.75f; 124 125 /** 126 * 用于桶转换为树的阀值 ,当添加一个节点到一个有多个节点的桶中时,超过阀值转化为树 127 * 该值必须大于2,并且至少应为8,以与树移除中的假设相吻合,在收缩后转换为桶。 128 */ 129 static final int TREEIFY_THRESHOLD = 8; 130 131 /** 132 * 在重新调整大小操作期间,非树化的计数阈值。应小于TeeIFIY阈值,最多6个网格与收缩检测下去除。 133 */ 134 135 static final int UNTREEIFY_THRESHOLD = 6; 136 137 /** 138 * 容器可被树化的最小表容量。 139 * 如果表中的节点太多,则重新调整表大小 140 * 应该至少有 4*TREEIFY_THRESHOLD ,以避免调整大小和树化阈值之间的冲突。 141 */ 142 static final int MIN_TREEIFY_CAPACITY = 64; 143 144 /** 145 * 基本节点,用于大多数条目 146 */ 147 static class Node<K,V> implements Map.Entry<K,V> { 148 final int hash; 149 final K key; 150 V value; 151 Node<K,V> next; 152 153 Node(int hash, K key, V value, Node<K,V> next) { 154 this.hash = hash; 155 this.key = key; 156 this.value = value; 157 this.next = next; 158 } 159 160 public final K getKey() { return key; } 161 public final V getValue() { return value; } 162 public final String toString() { return key + "=" + value; } 163 164 public final int hashCode() { 165 return Objects.hashCode(key) ^ Objects.hashCode(value); 166 } 167 168 public final V setValue(V newValue) { 169 V oldValue = value; 170 value = newValue; 171 return oldValue; 172 } 173 174 public final boolean equals(Object o) { 175 if (o == this) 176 return true; 177 if (o instanceof Map.Entry) { 178 Map.Entry<?,?> e = (Map.Entry<?,?>)o; 179 if (Objects.equals(key, e.getKey()) && 180 Objects.equals(value, e.getValue())) 181 return true; 182 } 183 return false; 184 } 185 } 186 187 /* ---------------- 静态方法 -------------- */ 188 189 /** 190 * 计算KEY.HASCODE()和散列(XOR)更高的散列位。 191 * 因为表使用power-of-two,所以仅在当前掩码上方的位上变化的散列集合总是会发生碰撞。 192 * (已知的例子是在小表中持有连续整数的浮动键集)。 193 * 因此,我们应用一种将更高比特的影响向下传播的变换。在比特扩展的速度、效用和质量之间存在权衡。 194 * 因为许多公共散列集已经合理地分布了(因此不能从扩展中受益),并且因为我们使用树来处理容器中的大型冲突集 195 * ,所以我们只以最便宜的方式异或某些移位的位,以减少系统损失,以及合并最高的位,否则将永远不会在索引计算中使用,因为表的边界。 196 */ 197 198 static final int hash(Object key) { 199 int h; 200 return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16); 201 } 202 203 /** 204 * 如果他是Comparable的子类返回 x 的类 , 否则返回null 205 */ 206 static Class<?> comparableClassFor(Object x) { 207 if (x instanceof Comparable) { 208 Class<?> c; Type[] ts, as; Type t; ParameterizedType p; 209 if ((c = x.getClass()) == String.class) // bypass checks 210 return c; 211 if ((ts = c.getGenericInterfaces()) != null) { 212 for (int i = 0; i < ts.length; ++i) { 213 if (((t = ts[i]) instanceof ParameterizedType) && 214 ((p = (ParameterizedType)t).getRawType() == Comparable.class) && 215 (as = p.getActualTypeArguments()) != null && 216 as.length == 1 && as[0] == c) // type arg is c 217 return c; 218 } 219 } 220 } 221 return null; 222 } 223 224 /** 225 * 如果x匹配kc (k的隐藏比较类) 返回k与x的比较值 否则返回0 226 */ 227 @SuppressWarnings({"rawtypes","unchecked"}) // for cast to Comparable 228 static int compareComparables(Class<?> kc, Object k, Object x) { 229 return (x == null || x.getClass() != kc ? 0 : ((Comparable)k).compareTo(x)); 230 } 231 232 /** 233 * 返回一个最接近的2的次幂的权值,用来给目标作为容量 234 * 235 * 此方法返回值为比参数大的,最接近的,2的幂数的值 236 */ 237 static final int tableSizeFor(int cap) { 238 int n = cap - 1; 239 n |= n >>> 1; 240 n |= n >>> 2; 241 n |= n >>> 4; 242 n |= n >>> 8; 243 n |= n >>> 16; 244 return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1; 245 } 246 247 /* ---------------- 字段 -------------- */ 248 249 250 251 /** 252 *表,在第一次使用时初始化,并根据需要调整大小。分配时,长度总是两个幂。 253 *(在某些操作中,我们也允许长度为零,以允许当前不需要的引导机制)。 254 */ 255 transient Node<K,V>[] table; 256 257 /** 258 * 保存缓存的entrySet ,注意在抽象类AbstractMap的字段中,用与keySet和values 259 */ 260 transient Set<Entry<K,V>> entrySet; 261 262 /** 263 * map 中 key - value 映射的总数 264 * 265 */ 266 transient int size; 267 268 /** 269 * 这个map 被 修改结构的次数, 270 * 这个字段用于使 HashMap 的 Collection-views 上的迭代器 fail-fast 参见 ConcurrentModificationException 271 */ 272 transient int modCount; 273 274 /** 275 * 临界值 需要调整大小的大小,键值对数量达到threshold后,需要扩容 容量*负载因子 capacity * loadfactor 276 */ 277 int threshold; 278 279 /** 280 * hash 表的 负载因子 281 */ 282 final float loadFactor; 283 284 /*---------------- 公共方法 -------------- */ 285 286 /** 287 * 构造具有指定初始容量和负载因子的空HashMap。 288 * @param initialCapacity 初始容量 289 * @param loadFactor 负载因子 290 * @throws IllegalArgumentException 如果初始容量为负或负载因子为非正 291 */ 292 public HashMap(int initialCapacity, float loadFactor) { 293 if (initialCapacity < 0) 294 throw new IllegalArgumentException("Illegal initial capacity: " + 295 initialCapacity); 296 if (initialCapacity > MAXIMUM_CAPACITY) 297 initialCapacity = MAXIMUM_CAPACITY; 298 if (loadFactor <= 0 || Float.isNaN(loadFactor)) 299 throw new IllegalArgumentException("Illegal load factor: " + 300 loadFactor); 301 this.loadFactor = loadFactor; 302 this.threshold = tableSizeFor(initialCapacity); 303 } 304 305 /** 306 * 构造具有指定初始容量和默认负载因子(0.75)的空HashMap。 307 */ 308 public HashMap(int initialCapacity) { 309 this(initialCapacity, DEFAULT_LOAD_FACTOR); 310 } 311 312 /** 313 * 构造具有默认初始容量(16)和负载因子(0.75)的空HashMap 314 */ 315 public HashMap() { 316 this.loadFactor = DEFAULT_LOAD_FACTOR; // all other fields defaulted 317 } 318 319 /** 320 *构造一个新的哈希图,其映射与指定的映射相同。 321 *创建HashMap时具有默认的负载因子(0.75)和足够的初始容量,以便将映射保存在指定的Map中。 322 */ 323 public HashMap(Map<? extends K, ? extends V> m) { 324 this.loadFactor = DEFAULT_LOAD_FACTOR; 325 putMapEntries(m, false); 326 } 327 328 /** 329 * 实现 Map.putAll 和 Map 构造函数 330 */ 331 final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) { 332 int s = m.size(); 333 if (s > 0) { 334 if (table == null) { // pre-size 335 float ft = ((float)s / loadFactor) + 1.0F; //得出map最小容量 容量 * 负载因子 = 实际键值对数量 336 337 int t = ((ft < (float)MAXIMUM_CAPACITY) ? (int)ft : MAXIMUM_CAPACITY); 338 339 if (t > threshold) 340 threshold = tableSizeFor(t);//重新计算阀值,获取合适的容量 341 } 342 else if (s > threshold) 343 resize();//超过容量则扩容 344 //将目标map中的键值对放入此map中 345 for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) { 346 K key = e.getKey(); 347 V value = e.getValue(); 348 putVal(hash(key), key, value, false, evict); 349 } 350 } 351 } 352 353 /** 354 * 返回 键值对的数量 355 */ 356 public int size() { 357 return size; 358 } 359 360 /** 361 * 返回 容器是否为空 362 */ 363 public boolean isEmpty() { 364 return size == 0; 365 } 366 367 /** 368 * 返回指定的键映射到的值,如果该映射不包含该键的映射 返回null。 369 * 返回null 不一定不包含key 也可能存的就是null 370 */ 371 372 public V get(Object key) { 373 Node<K,V> e; 374 return (e = getNode(hash(key), key)) == null ? null : e.value; 375 } 376 377 /** 378 * 实现Map.get 和相关方法 379 */ 380 final Node<K,V> getNode(int hash, Object key) { 381 Node<K,V>[] tab; Node<K,V> first, e; int n; K k; 382 // 当前tab 不为空,并且长度大于0 并且存在hash对应的桶中有值 383 if ((tab = table) != null && (n = tab.length) > 0 && (first = tab[(n - 1) & hash]) != null) { 384 // 总是检查第一个节点 385 if (first.hash == hash && ((k = first.key) == key || (key != null && key.equals(k)))) 386 return first; 387 if ((e = first.next) != null) { 388 //如果为树节点 389 if (first instanceof TreeNode) 390 //从树中获取节点 391 return ((TreeNode<K,V>)first).getTreeNode(hash, key); 392 do { 393 //从桶中获取节点 394 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) 395 return e; 396 } while ((e = e.next) != null); 397 } 398 } 399 return null; 400 } 401 402 /** 403 * 返回map是否包含指定key 404 */ 405 public boolean containsKey(Object key) { 406 return getNode(hash(key), key) != null; 407 } 408 409 /** 410 * 将指定key-value 关联放入map 411 * 如果之前存在key 则替换旧值 412 * 返回旧值或null 413 */ 414 public V put(K key, V value) { 415 return putVal(hash(key), key, value, false, true); 416 } 417 418 /** 419 * 实现Map.put 和相关方法 * 420 * @param hash hash for key 421 * @param key the key 422 * @param value the value to put 423 * @param onlyIfAbsent 如果为true 不改变现有的值 424 * @param evict 如果 false 则表处于创建模式 425 * @return 返回之前key映射的值 426 */ 427 final V putVal(int hash, K key, V value, boolean onlyIfAbsent, 428 boolean evict) { 429 Node<K,V>[] tab; Node<K,V> p; int n, i; 430 //tab为空则初始化tab 431 if ((tab = table) == null || (n = tab.length) == 0) 432 n = (tab = resize()).length; 433 //如果目标桶为空,直接存入 434 if ((p = tab[i = (n - 1) & hash]) == null) 435 tab[i] = newNode(hash, key, value, null); 436 //目标桶不为空,发生hash碰撞 437 else { 438 Node<K,V> e; K k; 439 //先判断桶顶或树顶,key值是否相同 440 if (p.hash == hash && ((k = p.key) == key || (key != null && key.equals(k)))) 441 e = p; 442 //判断是否为树节点 443 else if (p instanceof TreeNode) 444 //存入树节点中,根据key排序,存入相应位置 445 e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value); 446 //桶节点 447 else { 448 for (int binCount = 0; ; ++binCount) { 449 //如果下一个节点为空 450 if ((e = p.next) == null) { 451 //直接放入下一个节点 452 p.next = newNode(hash, key, value, null); 453 //如果桶长度,达到转化为树的要求 454 if (binCount >= TREEIFY_THRESHOLD - 1) // -1 for 1st 455 //转化为树 456 treeifyBin(tab, hash); 457 break;//直接返回e 458 } 459 //下一个节点不为空, 判断下一个key是否与目标key相同 460 if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) 461 break;//直接返回e 462 p = e;//没遇到,继续循环下一个 463 } 464 } 465 //存在目标key相同, 替换旧值 466 if (e != null) { // existing mapping for key 467 V oldValue = e.value; 468 if (!onlyIfAbsent || oldValue == null) 469 e.value = value; 470 afterNodeAccess(e); 471 return oldValue; 472 } 473 } 474 ++modCount; 475 //长度达到扩容要求,就扩容 476 if (++size > threshold) 477 resize(); 478 afterNodeInsertion(evict); 479 return null; 480 } 481 482 /** 483 * 初始化或者变为之前的2倍大小 , 如果为空,则按照保持在字段阈值中的初始容量目标分配。 484 * 否则,因为我们使用的是二倍展开的幂,所以每个桶中的元素必须保持在相同的索引上,或者在新表中以2次幂移动。 485 * @return the table 486 */ 487 final Node<K,V>[] resize() { 488 Node<K,V>[] oldTab = table; 489 int oldCap = (oldTab == null) ? 0 : oldTab.length; 490 int oldThr = threshold; 491 int newCap, newThr = 0; 492 //如果之前的容量大于0 493 if (oldCap > 0) { 494 //容量大于2的30次幂后, 说明容量已经达到最大值 2的31次幂 495 if (oldCap >= MAXIMUM_CAPACITY) { 496 //将临界值也调整为2的31次幂,达到map容量的最大值 497 threshold = Integer.MAX_VALUE; 498 //直接返回 499 return oldTab; 500 } 501 //扩容为之前的二倍后,小于2的30次幂,并且之前的容量大于默认值 502 else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY && 503 oldCap >= DEFAULT_INITIAL_CAPACITY) 504 newThr = oldThr << 1; // 临界值也 *2 505 } 506 else if (oldThr > 0) // 初始容量置于阈值 507 newCap = oldThr; 508 else { // 零初始阈值意味着使用默认值 509 newCap = DEFAULT_INITIAL_CAPACITY; 510 newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY); 511 } 512 if (newThr == 0) { 513 //容量*负载因子 514 float ft = (float)newCap * loadFactor; 515 //容量小于2的30次幂 并且临界值小于2的30次幂,那就使用临界值,否则直接使用最大值 516 newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ? (int)ft : Integer.MAX_VALUE); 517 } 518 //将临界值调整为新的临界值 519 threshold = newThr; 520 @SuppressWarnings({"rawtypes","unchecked"}) 521 Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap]; 522 //tab 替换为扩容后的tab 523 table = newTab; 524 //旧tab不为空 525 if (oldTab != null) { 526 //循环旧tab 527 for (int j = 0; j < oldCap; ++j) { 528 Node<K,V> e; 529 //如果当前位置有值 530 if ((e = oldTab[j]) != null) { 531 oldTab[j] = null; 532 //桶中只有一个值,直接放入新表中对应的位置 533 if (e.next == null) 534 newTab[e.hash & (newCap - 1)] = e; 535 //如果为树节点 536 else if (e instanceof TreeNode) 537 //将树分裂到新的tab中 538 ((TreeNode<K,V>)e).split(this, newTab, j, oldCap); 539 else { // 如果为桶,则维护顺序 540 //低位桶 541 Node<K,V> loHead = null, loTail = null; 542 //高位桶 543 Node<K,V> hiHead = null, hiTail = null; 544 Node<K,V> next; 545 do { 546 next = e.next; 547 //e的hash值,最高位为0, 表示放入的位置与之前相同 548 if ((e.hash & oldCap) == 0) { 549 if (loTail == null) 550 loHead = e; 551 else 552 loTail.next = e; 553 loTail = e; 554 } 555 //e的hash值,最高位为1, 表示放入的位置等于之前的位置+oldCap 556 else { 557 if (hiTail == null) 558 hiHead = e; 559 else 560 hiTail.next = e; 561 hiTail = e; 562 } 563 } while ((e = next) != null); 564 //将高位桶和低位桶分别放入对应的位置 565 if (loTail != null) { 566 loTail.next = null; 567 newTab[j] = loHead; 568 } 569 if (hiTail != null) { 570 hiTail.next = null; 571 newTab[j + oldCap] = hiHead; 572 } 573 } 574 } 575 } 576 } 577 return newTab; 578 } 579 580 /** 581 * 将桶树化 替换给定哈希索引中的所有链表节点,除非表太小,在这种情况下,调整大小。 582 */ 583 final void treeifyBin(Node<K,V>[] tab, int hash) { 584 int n, index; Node<K,V> e; 585 //是否达到树化所需要的最小表容量 586 if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY) 587 resize(); 588 //元素所在位置桶不为空 589 else if ((e = tab[index = (n - 1) & hash]) != null) { 590 TreeNode<K,V> hd = null, tl = null; 591 do { 592 //循环将节点转化为树节点 593 TreeNode<K,V> p = replacementTreeNode(e, null); 594 if (tl == null) 595 hd = p; 596 else { 597 p.prev = tl; 598 tl.next = p; 599 } 600 tl = p; 601 } while ((e = e.next) != null); 602 //将树节点,树形化 603 if ((tab[index] = hd) != null) 604 hd.treeify(tab); 605 } 606 } 607 608 /** 609 * 从指定map抄写全部的键值对到此map 610 * 这些映射将替换该映射对当前在指定映射中的任何键的任何映射。 611 * @param m mappings to be stored in this map 612 * @throws NullPointerException if the specified map is null 613 */ 614 public void putAll(Map<? extends K, ? extends V> m) { 615 putMapEntries(m, true); 616 } 617 618 /** 619 * 如果存在,则从该映射中移除指定键的映射。 620 */ 621 public V remove(Object key) { 622 Node<K,V> e; 623 return (e = removeNode(hash(key), key, null, false, true)) == null ? 624 null : e.value; 625 } 626 627 /** 628 * 实现Map.remove 和相关方法 629 * @param hash hash for key 630 * @param key the key 631 * @param value 匹配匹配值的值,否则忽略 632 * @param matchValue 如果为true,则仅在值相等时移除 633 * @param movable 如果false在移除时不移动其他节点 634 * @return the node, or null if none 635 */ 636 final Node<K,V> removeNode(int hash, Object key, Object value, 637 boolean matchValue, boolean movable) { 638 Node<K,V>[] tab; Node<K,V> p; int n, index; 639 if ((tab = table) != null && (n = tab.length) > 0 && 640 (p = tab[index = (n - 1) & hash]) != null) { 641 Node<K,V> node = null, e; K k; V v; 642 if (p.hash == hash && 643 ((k = p.key) == key || (key != null && key.equals(k)))) 644 node = p; 645 else if ((e = p.next) != null) { 646 if (p instanceof TreeNode) 647 node = ((TreeNode<K,V>)p).getTreeNode(hash, key); 648 else { 649 do { 650 if (e.hash == hash && 651 ((k = e.key) == key || 652 (key != null && key.equals(k)))) { 653 node = e; 654 break; 655 } 656 p = e; 657 } while ((e = e.next) != null); 658 } 659 } 660 if (node != null && (!matchValue || (v = node.value) == value || 661 (value != null && value.equals(v)))) { 662 if (node instanceof TreeNode) 663 ((TreeNode<K,V>)node).removeTreeNode(this, tab, movable); 664 else if (node == p) 665 tab[index] = node.next; 666 else 667 p.next = node.next; 668 ++modCount; 669 --size; 670 afterNodeRemoval(node); 671 return node; 672 } 673 } 674 return null; 675 } 676 677 /** 678 * 从该映射中移除所有映射。 679 *此调用返回后,map将为空。 680 */ 681 public void clear() { 682 Node<K,V>[] tab; 683 modCount++; 684 if ((tab = table) != null && size > 0) { 685 size = 0; 686 for (int i = 0; i < tab.length; ++i) 687 tab[i] = null; 688 } 689 } 690 691 /** 692 * 如果此映射将一个或多个键映射到指定值,则返回true。 693 */ 694 public boolean containsValue(Object value) { 695 Node<K,V>[] tab; V v; 696 if ((tab = table) != null && size > 0) { 697 for (int i = 0; i < tab.length; ++i) { 698 for (Node<K,V> e = tab[i]; e != null; e = e.next) { 699 if ((v = e.value) == value || 700 (value != null && value.equals(v))) 701 return true; 702 } 703 } 704 } 705 return false; 706 } 707 708 /** 709 * 返回map中所有的key的set集合 710 * 这个set由map支持,因此map的改变反应在set中,反之亦然 711 * 如果在对set进行迭代时,除了通过迭代器自己的移除操作之外,修改map,则迭代的结果是未定义的 712 * set支持元素删除,通过Set.remove, removeAll, retainAll, and clear操作从map中删除响应的键值对 713 * 它不支持add和addAll操作 714 */ 715 public Set<K> keySet() { 716 Set<K> ks = keySet; 717 if (ks == null) { 718 ks = new KeySet(); 719 keySet = ks; 720 } 721 return ks; 722 } 723 724 final class KeySet extends AbstractSet<K> { 725 public final int size() { return size; } 726 public final void clear() { HashMap.this.clear(); } 727 public final Iterator<K> iterator() { return new KeyIterator(); } 728 public final boolean contains(Object o) { return containsKey(o); } 729 public final boolean remove(Object key) { 730 return removeNode(hash(key), key, null, false, true) != null; 731 } 732 public final Spliterator<K> spliterator() { 733 return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0); 734 } 735 public final void forEach(Consumer<? super K> action) { 736 Node<K,V>[] tab; 737 if (action == null) 738 throw new NullPointerException(); 739 if (size > 0 && (tab = table) != null) { 740 int mc = modCount; 741 for (int i = 0; i < tab.length; ++i) { 742 for (Node<K,V> e = tab[i]; e != null; e = e.next) 743 action.accept(e.key); 744 } 745 if (modCount != mc) 746 throw new ConcurrentModificationException(); 747 } 748 } 749 } 750 751 /** 752 * 返回一个map中所有value的集合Collection 753 * 这个集合是由map支持的,所以map的改变会反应在集合中,反之亦然 754 * 如果在对集合进行迭代期间,除了通过迭代器自己的移除操作之外,修改map,则迭代的结果是未定义的 755 * 集合支持删除元素,通过Collection.remove, removeAll, retainAll and clear 操作,从map中删除对应的键值对, 756 * 它不支持add和addAll操作 757 * 758 * @return a view of the values contained in this map 759 */ 760 public Collection<V> values() { 761 Collection<V> vs = values; 762 if (vs == null) { 763 vs = new Values(); 764 values = vs; 765 } 766 return vs; 767 } 768 769 final class Values extends AbstractCollection<V> { 770 public final int size() { return size; } 771 public final void clear() { HashMap.this.clear(); } 772 public final Iterator<V> iterator() { return new ValueIterator(); } 773 public final boolean contains(Object o) { return containsValue(o); } 774 public final Spliterator<V> spliterator() { 775 return new ValueSpliterator<>(HashMap.this, 0, -1, 0, 0); 776 } 777 public final void forEach(Consumer<? super V> action) { 778 Node<K,V>[] tab; 779 if (action == null) 780 throw new NullPointerException(); 781 if (size > 0 && (tab = table) != null) { 782 int mc = modCount; 783 for (int i = 0; i < tab.length; ++i) { 784 for (Node<K,V> e = tab[i]; e != null; e = e.next) 785 action.accept(e.value); 786 } 787 if (modCount != mc) 788 throw new ConcurrentModificationException(); 789 } 790 } 791 } 792 793 /** 794 * 返回一个map中包含的所有键值对的set 795 * 这个set是由map支持的,所以对map的变化会反应在set中,反之亦然 796 * 如果在set迭代期间,除了通过迭代器自己的移除操作之外,修改map,则迭代的结果是未定义的 797 * 集合支持删除元素,通过Iterator.remove, 798 * Set.remove, removeAll, retainAll and 799 * clear操作,从map中删除对应的键值对 800 * 它不支持add和addAll操作 801 */ 802 public Set<Map.Entry<K,V>> entrySet() { 803 Set<Map.Entry<K,V>> es; 804 return (es = entrySet) == null ? (entrySet = new EntrySet()) : es; 805 } 806 807 final class EntrySet extends AbstractSet<Map.Entry<K,V>> { 808 public final int size() { return size; } 809 public final void clear() { HashMap.this.clear(); } 810 public final Iterator<Map.Entry<K,V>> iterator() { 811 return new EntryIterator(); 812 } 813 public final boolean contains(Object o) { 814 if (!(o instanceof Map.Entry)) 815 return false; 816 Map.Entry<?,?> e = (Map.Entry<?,?>) o; 817 Object key = e.getKey(); 818 Node<K,V> candidate = getNode(hash(key), key); 819 return candidate != null && candidate.equals(e); 820 } 821 public final boolean remove(Object o) { 822 if (o instanceof Map.Entry) { 823 Map.Entry<?,?> e = (Map.Entry<?,?>) o; 824 Object key = e.getKey(); 825 Object value = e.getValue(); 826 return removeNode(hash(key), key, value, true, true) != null; 827 } 828 return false; 829 } 830 public final Spliterator<Map.Entry<K,V>> spliterator() { 831 return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0); 832 } 833 public final void forEach(Consumer<? super Map.Entry<K,V>> action) { 834 Node<K,V>[] tab; 835 if (action == null) 836 throw new NullPointerException(); 837 if (size > 0 && (tab = table) != null) { 838 int mc = modCount; 839 for (int i = 0; i < tab.length; ++i) { 840 for (Node<K,V> e = tab[i]; e != null; e = e.next) 841 action.accept(e); 842 } 843 if (modCount != mc) 844 throw new ConcurrentModificationException(); 845 } 846 } 847 } 848 849 // 对JDK8 Map 扩展方法的重写 850 851 @Override 852 public V getOrDefault(Object key, V defaultValue) { 853 Node<K,V> e; 854 return (e = getNode(hash(key), key)) == null ? defaultValue : e.value; 855 } 856 857 @Override 858 public V putIfAbsent(K key, V value) { 859 return putVal(hash(key), key, value, true, true); 860 } 861 862 @Override 863 public boolean remove(Object key, Object value) { 864 return removeNode(hash(key), key, value, true, true) != null; 865 } 866 867 @Override 868 public boolean replace(K key, V oldValue, V newValue) { 869 Node<K,V> e; V v; 870 if ((e = getNode(hash(key), key)) != null && 871 ((v = e.value) == oldValue || (v != null && v.equals(oldValue)))) { 872 e.value = newValue; 873 afterNodeAccess(e); 874 return true; 875 } 876 return false; 877 } 878 879 @Override 880 public V replace(K key, V value) { 881 Node<K,V> e; 882 if ((e = getNode(hash(key), key)) != null) { 883 V oldValue = e.value; 884 e.value = value; 885 afterNodeAccess(e); 886 return oldValue; 887 } 888 return null; 889 } 890 891 @Override 892 public V computeIfAbsent(K key, 893 Function<? super K, ? extends V> mappingFunction) { 894 if (mappingFunction == null) 895 throw new NullPointerException(); 896 int hash = hash(key); 897 Node<K,V>[] tab; Node<K,V> first; int n, i; 898 int binCount = 0; 899 TreeNode<K,V> t = null; 900 Node<K,V> old = null; 901 if (size > threshold || (tab = table) == null || 902 (n = tab.length) == 0) 903 n = (tab = resize()).length; 904 if ((first = tab[i = (n - 1) & hash]) != null) { 905 if (first instanceof TreeNode) 906 old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key); 907 else { 908 Node<K,V> e = first; K k; 909 do { 910 if (e.hash == hash && 911 ((k = e.key) == key || (key != null && key.equals(k)))) { 912 old = e; 913 break; 914 } 915 ++binCount; 916 } while ((e = e.next) != null); 917 } 918 V oldValue; 919 if (old != null && (oldValue = old.value) != null) { 920 afterNodeAccess(old); 921 return oldValue; 922 } 923 } 924 V v = mappingFunction.apply(key); 925 if (v == null) { 926 return null; 927 } else if (old != null) { 928 old.value = v; 929 afterNodeAccess(old); 930 return v; 931 } 932 else if (t != null) 933 t.putTreeVal(this, tab, hash, key, v); 934 else { 935 tab[i] = newNode(hash, key, v, first); 936 if (binCount >= TREEIFY_THRESHOLD - 1) 937 treeifyBin(tab, hash); 938 } 939 ++modCount; 940 ++size; 941 afterNodeInsertion(true); 942 return v; 943 } 944 945 public V computeIfPresent(K key, 946 BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 947 if (remappingFunction == null) 948 throw new NullPointerException(); 949 Node<K,V> e; V oldValue; 950 int hash = hash(key); 951 if ((e = getNode(hash, key)) != null && 952 (oldValue = e.value) != null) { 953 V v = remappingFunction.apply(key, oldValue); 954 if (v != null) { 955 e.value = v; 956 afterNodeAccess(e); 957 return v; 958 } 959 else 960 removeNode(hash, key, null, false, true); 961 } 962 return null; 963 } 964 965 @Override 966 public V compute(K key, 967 BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 968 if (remappingFunction == null) 969 throw new NullPointerException(); 970 int hash = hash(key); 971 Node<K,V>[] tab; Node<K,V> first; int n, i; 972 int binCount = 0; 973 TreeNode<K,V> t = null; 974 Node<K,V> old = null; 975 if (size > threshold || (tab = table) == null || 976 (n = tab.length) == 0) 977 n = (tab = resize()).length; 978 if ((first = tab[i = (n - 1) & hash]) != null) { 979 if (first instanceof TreeNode) 980 old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key); 981 else { 982 Node<K,V> e = first; K k; 983 do { 984 if (e.hash == hash && 985 ((k = e.key) == key || (key != null && key.equals(k)))) { 986 old = e; 987 break; 988 } 989 ++binCount; 990 } while ((e = e.next) != null); 991 } 992 } 993 V oldValue = (old == null) ? null : old.value; 994 V v = remappingFunction.apply(key, oldValue); 995 if (old != null) { 996 if (v != null) { 997 old.value = v; 998 afterNodeAccess(old); 999 } 1000 else 1001 removeNode(hash, key, null, false, true); 1002 } 1003 else if (v != null) { 1004 if (t != null) 1005 t.putTreeVal(this, tab, hash, key, v); 1006 else { 1007 tab[i] = newNode(hash, key, v, first); 1008 if (binCount >= TREEIFY_THRESHOLD - 1) 1009 treeifyBin(tab, hash); 1010 } 1011 ++modCount; 1012 ++size; 1013 afterNodeInsertion(true); 1014 } 1015 return v; 1016 } 1017 1018 @Override 1019 public V merge(K key, V value, 1020 BiFunction<? super V, ? super V, ? extends V> remappingFunction) { 1021 if (value == null) 1022 throw new NullPointerException(); 1023 if (remappingFunction == null) 1024 throw new NullPointerException(); 1025 int hash = hash(key); 1026 Node<K,V>[] tab; Node<K,V> first; int n, i; 1027 int binCount = 0; 1028 TreeNode<K,V> t = null; 1029 Node<K,V> old = null; 1030 if (size > threshold || (tab = table) == null || 1031 (n = tab.length) == 0) 1032 n = (tab = resize()).length; 1033 if ((first = tab[i = (n - 1) & hash]) != null) { 1034 if (first instanceof TreeNode) 1035 old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key); 1036 else { 1037 Node<K,V> e = first; K k; 1038 do { 1039 if (e.hash == hash && 1040 ((k = e.key) == key || (key != null && key.equals(k)))) { 1041 old = e; 1042 break; 1043 } 1044 ++binCount; 1045 } while ((e = e.next) != null); 1046 } 1047 } 1048 if (old != null) { 1049 V v; 1050 if (old.value != null) 1051 v = remappingFunction.apply(old.value, value); 1052 else 1053 v = value; 1054 if (v != null) { 1055 old.value = v; 1056 afterNodeAccess(old); 1057 } 1058 else 1059 removeNode(hash, key, null, false, true); 1060 return v; 1061 } 1062 if (value != null) { 1063 if (t != null) 1064 t.putTreeVal(this, tab, hash, key, value); 1065 else { 1066 tab[i] = newNode(hash, key, value, first); 1067 if (binCount >= TREEIFY_THRESHOLD - 1) 1068 treeifyBin(tab, hash); 1069 } 1070 ++modCount; 1071 ++size; 1072 afterNodeInsertion(true); 1073 } 1074 return value; 1075 } 1076 1077 @Override 1078 public void forEach(BiConsumer<? super K, ? super V> action) { 1079 Node<K,V>[] tab; 1080 if (action == null) 1081 throw new NullPointerException(); 1082 if (size > 0 && (tab = table) != null) { 1083 int mc = modCount; 1084 for (int i = 0; i < tab.length; ++i) { 1085 for (Node<K,V> e = tab[i]; e != null; e = e.next) 1086 action.accept(e.key, e.value); 1087 } 1088 if (modCount != mc) 1089 throw new ConcurrentModificationException(); 1090 } 1091 } 1092 1093 @Override 1094 public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) { 1095 Node<K,V>[] tab; 1096 if (function == null) 1097 throw new NullPointerException(); 1098 if (size > 0 && (tab = table) != null) { 1099 int mc = modCount; 1100 for (int i = 0; i < tab.length; ++i) { 1101 for (Node<K,V> e = tab[i]; e != null; e = e.next) { 1102 e.value = function.apply(e.key, e.value); 1103 } 1104 } 1105 if (modCount != mc) 1106 throw new ConcurrentModificationException(); 1107 } 1108 } 1109 1110 /*------------------------------------------------------------ */ 1111 // 克隆和序列化 1112 1113 /** 1114 * 返回此哈希映射实例的浅拷贝:键和值本身不被克隆。 1115 * 1116 * @return a shallow copy of this map 1117 */ 1118 @SuppressWarnings("unchecked") 1119 @Override 1120 public Object clone() { 1121 HashMap<K,V> result; 1122 try { 1123 result = (HashMap<K,V>)super.clone(); 1124 } catch (CloneNotSupportedException e) { 1125 // 这不应该发生,因为我们是克隆的 1126 throw new InternalError(e); 1127 } 1128 result.reinitialize(); 1129 result.putMapEntries(this, false); 1130 return result; 1131 } 1132 1133 // 序列化HashSet时也使用这些方法 1134 final float loadFactor() { return loadFactor; } 1135 final int capacity() { 1136 return (table != null) ? table.length : 1137 (threshold > 0) ? threshold : 1138 DEFAULT_INITIAL_CAPACITY; 1139 } 1140 1141 /** 1142 * 将HashMap 实例,保存到流中 * 1143 * 序列化的数据: HashMap的容量(桶数组的长度),然后是size(键值对的数量),然后是key和value, 1144 * 键值对 没有特定的顺序 1145 */ 1146 private void writeObject(java.io.ObjectOutputStream s) 1147 throws IOException { 1148 int buckets = capacity(); 1149 // 写出阈值、负载因子和任何隐藏的内容 1150 s.defaultWriteObject(); 1151 s.writeInt(buckets); 1152 s.writeInt(size); 1153 internalWriteEntries(s); 1154 } 1155 1156 /** 1157 * 从流中重新构造HashMap实例,即反序列化 1158 */ 1159 private void readObject(java.io.ObjectInputStream s) 1160 throws IOException, ClassNotFoundException { 1161 // 读取阈值(忽略)、负载因子和任何隐藏的内容 1162 s.defaultReadObject(); 1163 reinitialize(); 1164 if (loadFactor <= 0 || Float.isNaN(loadFactor)) 1165 throw new InvalidObjectException("Illegal load factor: " + 1166 loadFactor); 1167 s.readInt(); // 阅读并忽略桶的数量 1168 int mappings = s.readInt(); // 读取映射数(大小) 1169 if (mappings < 0) 1170 throw new InvalidObjectException("Illegal mappings count: " + 1171 mappings); 1172 else if (mappings > 0) { // (if zero, use defaults) 1173 // 只有在内部时,才使用给定的负载因子来调整表的大小 1174 // range of 0.25...4.0 1175 float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f); 1176 float fc = (float)mappings / lf + 1.0f; 1177 int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ? 1178 DEFAULT_INITIAL_CAPACITY : 1179 (fc >= MAXIMUM_CAPACITY) ? 1180 MAXIMUM_CAPACITY : 1181 tableSizeFor((int)fc)); 1182 float ft = (float)cap * lf; 1183 threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ? 1184 (int)ft : Integer.MAX_VALUE); 1185 1186 // 检查map.entry[]。类,因为它是最接近我们实际创建的公共类型。 1187 SharedSecrets.getJavaOISAccess().checkArray(s, Map.Entry[].class, cap); 1188 @SuppressWarnings({"rawtypes","unchecked"}) 1189 Node<K,V>[] tab = (Node<K,V>[])new Node[cap]; 1190 table = tab; 1191 1192 // 读取键和值,并将映射放入HashMap中 1193 for (int i = 0; i < mappings; i++) { 1194 @SuppressWarnings("unchecked") 1195 K key = (K) s.readObject(); 1196 @SuppressWarnings("unchecked") 1197 V value = (V) s.readObject(); 1198 putVal(hash(key), key, value, false, false); 1199 } 1200 } 1201 } 1202 1203 /*------------------------------------------------------------ */ 1204 // 迭代器 1205 1206 abstract class HashIterator { 1207 Node<K,V> next; // next entry to return 1208 Node<K,V> current; // current entry 1209 int expectedModCount; // for fast-fail 1210 int index; // current slot 1211 1212 HashIterator() { 1213 expectedModCount = modCount; 1214 Node<K,V>[] t = table; 1215 current = next = null; 1216 index = 0; 1217 if (t != null && size > 0) { // advance to first entry 1218 do {} while (index < t.length && (next = t[index++]) == null); 1219 } 1220 } 1221 1222 public final boolean hasNext() { 1223 return next != null; 1224 } 1225 1226 final Node<K,V> nextNode() { 1227 Node<K,V>[] t; 1228 Node<K,V> e = next; 1229 if (modCount != expectedModCount) 1230 throw new ConcurrentModificationException(); 1231 if (e == null) 1232 throw new NoSuchElementException(); 1233 if ((next = (current = e).next) == null && (t = table) != null) { 1234 do {} while (index < t.length && (next = t[index++]) == null); 1235 } 1236 return e; 1237 } 1238 1239 public final void remove() { 1240 Node<K,V> p = current; 1241 if (p == null) 1242 throw new IllegalStateException(); 1243 if (modCount != expectedModCount) 1244 throw new ConcurrentModificationException(); 1245 current = null; 1246 K key = p.key; 1247 removeNode(hash(key), key, null, false, false); 1248 expectedModCount = modCount; 1249 } 1250 } 1251 1252 final class KeyIterator extends HashIterator 1253 implements Iterator<K> { 1254 public final K next() { return nextNode().key; } 1255 } 1256 1257 final class ValueIterator extends HashIterator 1258 implements Iterator<V> { 1259 public final V next() { return nextNode().value; } 1260 } 1261 1262 final class EntryIterator extends HashIterator 1263 implements Iterator<Map.Entry<K,V>> { 1264 public final Map.Entry<K,V> next() { return nextNode(); } 1265 } 1266 1267 /*------------------------------------------------------------ */ 1268 // spliterators 1269 1270 static class HashMapSpliterator<K,V> { 1271 final HashMap<K,V> map; 1272 Node<K,V> current; // current node 1273 int index; // current index, modified on advance/split 1274 int fence; // one past last index 1275 int est; // size estimate 1276 int expectedModCount; // for comodification checks 1277 1278 HashMapSpliterator(HashMap<K,V> m, int origin, 1279 int fence, int est, 1280 int expectedModCount) { 1281 this.map = m; 1282 this.index = origin; 1283 this.fence = fence; 1284 this.est = est; 1285 this.expectedModCount = expectedModCount; 1286 } 1287 1288 final int getFence() { // 在第一次使用时初始化围栏和大小 1289 int hi; 1290 if ((hi = fence) < 0) { 1291 HashMap<K,V> m = map; 1292 est = m.size; 1293 expectedModCount = m.modCount; 1294 Node<K,V>[] tab = m.table; 1295 hi = fence = (tab == null) ? 0 : tab.length; 1296 } 1297 return hi; 1298 } 1299 1300 public final long estimateSize() { 1301 getFence(); // force init 1302 return (long) est; 1303 } 1304 } 1305 1306 static final class KeySpliterator<K,V> 1307 extends HashMapSpliterator<K,V> 1308 implements Spliterator<K> { 1309 KeySpliterator(HashMap<K,V> m, int origin, int fence, int est, 1310 int expectedModCount) { 1311 super(m, origin, fence, est, expectedModCount); 1312 } 1313 1314 public KeySpliterator<K,V> trySplit() { 1315 int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; 1316 return (lo >= mid || current != null) ? null : 1317 new KeySpliterator<>(map, lo, index = mid, est >>>= 1, 1318 expectedModCount); 1319 } 1320 1321 public void forEachRemaining(Consumer<? super K> action) { 1322 int i, hi, mc; 1323 if (action == null) 1324 throw new NullPointerException(); 1325 HashMap<K,V> m = map; 1326 Node<K,V>[] tab = m.table; 1327 if ((hi = fence) < 0) { 1328 mc = expectedModCount = m.modCount; 1329 hi = fence = (tab == null) ? 0 : tab.length; 1330 } 1331 else 1332 mc = expectedModCount; 1333 if (tab != null && tab.length >= hi && 1334 (i = index) >= 0 && (i < (index = hi) || current != null)) { 1335 Node<K,V> p = current; 1336 current = null; 1337 do { 1338 if (p == null) 1339 p = tab[i++]; 1340 else { 1341 action.accept(p.key); 1342 p = p.next; 1343 } 1344 } while (p != null || i < hi); 1345 if (m.modCount != mc) 1346 throw new ConcurrentModificationException(); 1347 } 1348 } 1349 1350 public boolean tryAdvance(Consumer<? super K> action) { 1351 int hi; 1352 if (action == null) 1353 throw new NullPointerException(); 1354 Node<K,V>[] tab = map.table; 1355 if (tab != null && tab.length >= (hi = getFence()) && index >= 0) { 1356 while (current != null || index < hi) { 1357 if (current == null) 1358 current = tab[index++]; 1359 else { 1360 K k = current.key; 1361 current = current.next; 1362 action.accept(k); 1363 if (map.modCount != expectedModCount) 1364 throw new ConcurrentModificationException(); 1365 return true; 1366 } 1367 } 1368 } 1369 return false; 1370 } 1371 1372 public int characteristics() { 1373 return (fence < 0 || est == map.size ? Spliterator.SIZED : 0) | 1374 Spliterator.DISTINCT; 1375 } 1376 } 1377 1378 static final class ValueSpliterator<K,V> 1379 extends HashMapSpliterator<K,V> 1380 implements Spliterator<V> { 1381 ValueSpliterator(HashMap<K,V> m, int origin, int fence, int est, 1382 int expectedModCount) { 1383 super(m, origin, fence, est, expectedModCount); 1384 } 1385 1386 public ValueSpliterator<K,V> trySplit() { 1387 int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; 1388 return (lo >= mid || current != null) ? null : 1389 new ValueSpliterator<>(map, lo, index = mid, est >>>= 1, 1390 expectedModCount); 1391 } 1392 1393 public void forEachRemaining(Consumer<? super V> action) { 1394 int i, hi, mc; 1395 if (action == null) 1396 throw new NullPointerException(); 1397 HashMap<K,V> m = map; 1398 Node<K,V>[] tab = m.table; 1399 if ((hi = fence) < 0) { 1400 mc = expectedModCount = m.modCount; 1401 hi = fence = (tab == null) ? 0 : tab.length; 1402 } 1403 else 1404 mc = expectedModCount; 1405 if (tab != null && tab.length >= hi && 1406 (i = index) >= 0 && (i < (index = hi) || current != null)) { 1407 Node<K,V> p = current; 1408 current = null; 1409 do { 1410 if (p == null) 1411 p = tab[i++]; 1412 else { 1413 action.accept(p.value); 1414 p = p.next; 1415 } 1416 } while (p != null || i < hi); 1417 if (m.modCount != mc) 1418 throw new ConcurrentModificationException(); 1419 } 1420 } 1421 1422 public boolean tryAdvance(Consumer<? super V> action) { 1423 int hi; 1424 if (action == null) 1425 throw new NullPointerException(); 1426 Node<K,V>[] tab = map.table; 1427 if (tab != null && tab.length >= (hi = getFence()) && index >= 0) { 1428 while (current != null || index < hi) { 1429 if (current == null) 1430 current = tab[index++]; 1431 else { 1432 V v = current.value; 1433 current = current.next; 1434 action.accept(v); 1435 if (map.modCount != expectedModCount) 1436 throw new ConcurrentModificationException(); 1437 return true; 1438 } 1439 } 1440 } 1441 return false; 1442 } 1443 1444 public int characteristics() { 1445 return (fence < 0 || est == map.size ? Spliterator.SIZED : 0); 1446 } 1447 } 1448 1449 static final class EntrySpliterator<K,V> 1450 extends HashMapSpliterator<K,V> 1451 implements Spliterator<Map.Entry<K,V>> { 1452 EntrySpliterator(HashMap<K,V> m, int origin, int fence, int est, 1453 int expectedModCount) { 1454 super(m, origin, fence, est, expectedModCount); 1455 } 1456 1457 public EntrySpliterator<K,V> trySplit() { 1458 int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; 1459 return (lo >= mid || current != null) ? null : 1460 new EntrySpliterator<>(map, lo, index = mid, est >>>= 1, 1461 expectedModCount); 1462 } 1463 1464 public void forEachRemaining(Consumer<? super Map.Entry<K,V>> action) { 1465 int i, hi, mc; 1466 if (action == null) 1467 throw new NullPointerException(); 1468 HashMap<K,V> m = map; 1469 Node<K,V>[] tab = m.table; 1470 if ((hi = fence) < 0) { 1471 mc = expectedModCount = m.modCount; 1472 hi = fence = (tab == null) ? 0 : tab.length; 1473 } 1474 else 1475 mc = expectedModCount; 1476 if (tab != null && tab.length >= hi && 1477 (i = index) >= 0 && (i < (index = hi) || current != null)) { 1478 Node<K,V> p = current; 1479 current = null; 1480 do { 1481 if (p == null) 1482 p = tab[i++]; 1483 else { 1484 action.accept(p); 1485 p = p.next; 1486 } 1487 } while (p != null || i < hi); 1488 if (m.modCount != mc) 1489 throw new ConcurrentModificationException(); 1490 } 1491 } 1492 1493 public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) { 1494 int hi; 1495 if (action == null) 1496 throw new NullPointerException(); 1497 Node<K,V>[] tab = map.table; 1498 if (tab != null && tab.length >= (hi = getFence()) && index >= 0) { 1499 while (current != null || index < hi) { 1500 if (current == null) 1501 current = tab[index++]; 1502 else { 1503 Node<K,V> e = current; 1504 current = current.next; 1505 action.accept(e); 1506 if (map.modCount != expectedModCount) 1507 throw new ConcurrentModificationException(); 1508 return true; 1509 } 1510 } 1511 } 1512 return false; 1513 } 1514 1515 public int characteristics() { 1516 return (fence < 0 || est == map.size ? Spliterator.SIZED : 0) | 1517 Spliterator.DISTINCT; 1518 } 1519 } 1520 1521 /* ------------------------------------------------------------ * / 1522 // LinkedHashMap support 1523 1524 1525 /* 1526 下面的包保护方法被设计成被LinkedHashMap覆盖,但不被任何其他子类覆盖。 1527 几乎所有其他内部方法都是包保护的,但都声明为final,因此可以由LinkedHashMap、视图类和HashSet使用。 1528 */ 1529 1530 // 创建一个常规(非树)节点 1531 Node<K,V> newNode(int hash, K key, V value, Node<K,V> next) { 1532 return new Node<>(hash, key, value, next); 1533 } 1534 1535 // 用于从treenode到普通节点的转换 1536 Node<K,V> replacementNode(Node<K,V> p, Node<K,V> next) { 1537 return new Node<>(p.hash, p.key, p.value, next); 1538 } 1539 1540 // 创建一个树bin节点 1541 TreeNode<K,V> newTreeNode(int hash, K key, V value, Node<K,V> next) { 1542 return new TreeNode<>(hash, key, value, next); 1543 } 1544 1545 /** 1546 * 将节点转化为树节点 1547 * @param p 1548 * @param next 1549 * @return 1550 */ 1551 TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) { 1552 return new TreeNode<>(p.hash, p.key, p.value, next); 1553 } 1554 1555 /** 1556 * 重置为初始默认状态。由克隆和readObject调用。 1557 */ 1558 void reinitialize() { 1559 table = null; 1560 entrySet = null; 1561 keySet = null; 1562 values = null; 1563 modCount = 0; 1564 threshold = 0; 1565 size = 0; 1566 } 1567 1568 /** 1569 * 回调允许LinkedHashMap后操作 1570 * @param p 1571 */ 1572 void afterNodeAccess(Node<K,V> p) { } 1573 /** 1574 * 回调允许LinkedHashMap后操作 1575 * @param p 1576 */ 1577 void afterNodeInsertion(boolean evict) { } 1578 /** 1579 * 回调允许LinkedHashMap后操作 1580 * @param p 1581 */ 1582 void afterNodeRemoval(Node<K,V> p) { } 1583 1584 // 仅从writeObject调用,以确保兼容排序。 1585 void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException { 1586 Node<K,V>[] tab; 1587 if (size > 0 && (tab = table) != null) { 1588 for (int i = 0; i < tab.length; ++i) { 1589 for (Node<K,V> e = tab[i]; e != null; e = e.next) { 1590 s.writeObject(e.key); 1591 s.writeObject(e.value); 1592 } 1593 } 1594 } 1595 } 1596 1597 /*------------------------------------------------------------ */ 1598 // Tree bins 1599 1600 /** 1601 * 仅从writeObject调用,以确保兼容排序。 1602 * Entry for Tree bins. Extends LinkedHashMap.Entry(它依次扩展节点)可以用作常规节点或链接节点的扩展。 1603 */ 1604 static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> { 1605 TreeNode<K,V> parent; // red-black tree links 1606 TreeNode<K,V> left; 1607 TreeNode<K,V> right; 1608 TreeNode<K,V> prev; // 删除后需要取消下一个链接 1609 boolean red; 1610 TreeNode(int hash, K key, V val, Node<K,V> next) { 1611 super(hash, key, val, next); 1612 } 1613 1614 /** 1615 * 返回包含此节点的树的根。 1616 */ 1617 final TreeNode<K,V> root() { 1618 for (TreeNode<K,V> r = this, p;;) { 1619 if ((p = r.parent) == null) 1620 return r; 1621 r = p; 1622 } 1623 } 1624 1625 /** 1626 * 重新调整树中的next链表关系,确保给定的根是其bin的第一个节点。 1627 */ 1628 static <K,V> void moveRootToFront(Node<K,V>[] tab, TreeNode<K,V> root) { 1629 int n; 1630 if (root != null && tab != null && (n = tab.length) > 0) { 1631 //此桶所在tab中的位置 1632 int index = (n - 1) & root.hash; 1633 //取出链表中的first 1634 TreeNode<K,V> first = (TreeNode<K,V>)tab[index]; 1635 if (root != first) { 1636 Node<K,V> rn; 1637 //将root从链表中取出,然后插入到first前面,并且将root放入tab中作为桶顶 1638 tab[index] = root; 1639 TreeNode<K,V> rp = root.prev; 1640 if ((rn = root.next) != null) 1641 ((TreeNode<K,V>)rn).prev = rp; 1642 if (rp != null) 1643 rp.next = rn; 1644 if (first != null) 1645 first.prev = root; 1646 root.next = first; 1647 root.prev = null; 1648 } 1649 assert checkInvariants(root); 1650 } 1651 } 1652 1653 /** 1654 * 使用给定的哈希和键查找从根p开始的节点。kc参数在首次使用比较键时缓存comparableClassFor(键)。 1655 */ 1656 final TreeNode<K,V> find(int h, Object k, Class<?> kc) { 1657 TreeNode<K,V> p = this; 1658 do { 1659 int ph, dir; K pk; 1660 TreeNode<K,V> pl = p.left, pr = p.right, q; 1661 //根据hash确定子树,遍历子树 1662 if ((ph = p.hash) > h) 1663 p = pl; 1664 //根据hash确定子树,遍历子树 1665 else if (ph < h) 1666 p = pr; 1667 //命中 1668 else if ((pk = p.key) == k || (k != null && k.equals(pk))) 1669 return p; 1670 //只有一条子树,遍历子树 1671 else if (pl == null) 1672 p = pr; 1673 //只有一条子树,遍历子树 1674 else if (pr == null) 1675 p = pl; 1676 //无法根据hash确定子树,通过kc确定顺序 1677 else if ((kc != null || (kc = comparableClassFor(k)) != null) && (dir = compareComparables(kc, k, pk)) != 0) 1678 p = (dir < 0) ? pl : pr; 1679 //也无法根据kc确定顺序,则直接从右子树查找, 1680 else if ((q = pr.find(h, k, kc)) != null) 1681 return q; 1682 //右子树查不到,查左子树 1683 else 1684 p = pl; 1685 } while (p != null); 1686 return null; 1687 } 1688 1689 /** 1690 * 调用查找根节点。 1691 */ 1692 final TreeNode<K,V> getTreeNode(int h, Object k) { 1693 return ((parent != null) ? root() : this).find(h, k, null); 1694 } 1695 1696 /** 1697 * 在相同的哈希码和不可比较的情况下,调用排序插入的破接实用程序。 1698 * 我们不需要一个总顺序,只需要一个一致的插入规则来保持重新平衡之间的等效性。超越必要的程度简化了对根节点的测试。 1699 */ 1700 static int tieBreakOrder(Object a, Object b) { 1701 int d; 1702 //如果a为null 或者b为null 获取 a和b 类名相同,则比较System的idHashCode,否则直接以类名的比较结果作为结论 1703 if (a == null || b == null || (d = a.getClass().getName().compareTo(b.getClass().getName())) == 0) 1704 1705 d = (System.identityHashCode(a) <= System.identityHashCode(b) ? -1 : 1); 1706 return d; 1707 } 1708 1709 /** 1710 * 形成从该节点链接的节点树。 1711 * @return root of tree 1712 */ 1713 final void treeify(Node<K,V>[] tab) { 1714 TreeNode<K,V> root = null; 1715 for (TreeNode<K,V> x = this, next; x != null; x = next) { 1716 next = (TreeNode<K,V>)x.next; 1717 x.left = x.right = null; 1718 //如果根节点为空,x为根节点,根节点为黑节点 1719 if (root == null) { 1720 x.parent = null; 1721 x.red = false; 1722 root = x; 1723 } 1724 else { 1725 //否则为其他节点 1726 K k = x.key; 1727 int h = x.hash; 1728 Class<?> kc = null; 1729 //从根开始遍历 1730 for (TreeNode<K,V> p = root;;) { 1731 int dir, ph; 1732 K pk = p.key; 1733 if ((ph = p.hash) > h) 1734 dir = -1; 1735 else if (ph < h) 1736 dir = 1; 1737 //如果hash相等,根据实现的比较类,比较大小 1738 //此处逻辑, 第一次循环, kc为null 获取k的比较类kc,如果获取到, kc不为null 进入||后面 1739 // 如果获取不到,直接进入方法 1740 //第二次循环,kc为null ,同上,kc不为空,直接进入||后面 1741 // 进入||后面,如果比较有结果,不进入方法,如果没有结果,与kc为null结果相同,进入方法进行对比k和pk 1742 else if ((kc == null && (kc = comparableClassFor(k)) == null) || (dir = compareComparables(kc, k, pk)) == 0) 1743 dir = tieBreakOrder(k, pk); 1744 //得出 dir 为 k 和 pk 比较结果 1745 //如果p的左右子树不为null 则继续比较左右子树,直至要插入的子节点为null,将x放入p的左子节点或右子节点 1746 TreeNode<K,V> xp = p; 1747 if ((p = (dir <= 0) ? p.left : p.right) == null) { 1748 x.parent = xp; 1749 if (dir <= 0) 1750 xp.left = x; 1751 else 1752 xp.right = x; 1753 //插入新的节点后可能破坏结构,需要调整树 1754 root = balanceInsertion(root, x); 1755 break; 1756 } 1757 } 1758 } 1759 } 1760 //重新调整树中节点的next链表关系 1761 moveRootToFront(tab, root); 1762 } 1763 1764 /** 1765 * 非树化 返回一个非treenode列表,替换从该节点链接的那些。 1766 */ 1767 final Node<K,V> untreeify(HashMap<K,V> map) { 1768 Node<K,V> hd = null, tl = null; 1769 for (Node<K,V> q = this; q != null; q = q.next) { 1770 //将所有树节点转换为普通节点 1771 Node<K,V> p = map.replacementNode(q, null); 1772 if (tl == null) 1773 hd = p; 1774 else 1775 tl.next = p; 1776 tl = p; 1777 } 1778 return hd; 1779 } 1780 1781 /** 1782 * 树版本的putVal。 1783 */ 1784 final TreeNode<K,V> putTreeVal(HashMap<K,V> map, Node<K,V>[] tab, int h, K k, V v) { 1785 Class<?> kc = null; 1786 boolean searched = false; 1787 TreeNode<K,V> root = (parent != null) ? root() : this; 1788 //从根节点开始遍历 1789 for (TreeNode<K,V> p = root;;) { 1790 int dir, ph; K pk; 1791 if ((ph = p.hash) > h) 1792 dir = -1; 1793 else if (ph < h) 1794 dir = 1; 1795 //key命中 1796 else if ((pk = p.key) == k || (k != null && k.equals(pk))) 1797 return p; 1798 //key未命中,根据kc得出的顺序命中或无法得出顺序 1799 else if ((kc == null && (kc = comparableClassFor(k)) == null) || (dir = compareComparables(kc, k, pk)) == 0) { 1800 if (!searched) { 1801 TreeNode<K,V> q, ch; 1802 searched = true; 1803 //查找p的左子树和右子树,如果查到命中节点,则返回 1804 if (((ch = p.left) != null && (q = ch.find(h, k, kc)) != null) || 1805 ((ch = p.right) != null && (q = ch.find(h, k, kc)) != null)) 1806 return q; 1807 } 1808 dir = tieBreakOrder(k, pk); 1809 } 1810 //得出大小顺序 dir 1811 TreeNode<K,V> xp = p; 1812 //如果根据得出的顺序,渠道的子树为null,则直接插入相应位置,否则继续遍历子树 1813 if ((p = (dir <= 0) ? p.left : p.right) == null) { 1814 Node<K,V> xpn = xp.next; 1815 TreeNode<K,V> x = map.newTreeNode(h, k, v, xpn); 1816 if (dir <= 0) 1817 xp.left = x; 1818 else 1819 xp.right = x; 1820 xp.next = x; 1821 x.parent = x.prev = xp; 1822 if (xpn != null) 1823 ((TreeNode<K,V>)xpn).prev = x; 1824 //调整树结构以及双链表结构 1825 moveRootToFront(tab, balanceInsertion(root, x)); 1826 return null; 1827 } 1828 } 1829 } 1830 1831 /** 1832 * 移除指定的节点,该节点必须在此调用之前出现。 1833 * 这比典型的红黑删除代码要混乱得多,因为我们不能用在遍历期间可以独立访问的“next”指针固定的叶子继承节点来交换内部节点的内容。 1834 * 所以我们交换树连杆。 1835 * 如果当前树看起来节点太少,那么bin将被转换回普通bin。(根据树的结构,测试在2到6个节点之间触发)。 1836 */ 1837 final void removeTreeNode(HashMap<K,V> map, Node<K,V>[] tab, boolean movable) { 1838 int n; 1839 if (tab == null || (n = tab.length) == 0) 1840 return; 1841 int index = (n - 1) & hash; 1842 TreeNode<K,V> first = (TreeNode<K,V>)tab[index], root = first, rl; 1843 TreeNode<K,V> succ = (TreeNode<K,V>)next, pred = prev; 1844 //如果此节点前面没有节点,则其为通顶&树根, 直接移除,然后下一个节点接上 1845 if (pred == null) 1846 tab[index] = first = succ; 1847 else 1848 pred.next = succ; 1849 if (succ != null) 1850 succ.prev = pred; 1851 //桶中没有元素了 1852 if (first == null) 1853 return; 1854 1855 if (root.parent != null)//此处没看懂在什么情况下会出现,理论上不存在 1856 root = root.root(); 1857 1858 if (root == null || root.right == null || (rl = root.left) == null || rl.left == null) { 1859 tab[index] = first.untreeify(map); // 最大的可能就是rl.left==null ,其他 节点都存在,长度为6 1860 return; 1861 } 1862 TreeNode<K,V> p = this, pl = left, pr = right, replacement; 1863 //如果左右子节点都存在 1864 if (pl != null && pr != null) { 1865 TreeNode<K,V> s = pr, sl; 1866 while ((sl = s.left) != null) // 寻找接班人 比当前节点大的,最小的一个节点 1867 s = sl; 1868 //将s和p交换位置 交换颜色 1869 //将p的左子树接到s的左子树,s的左子树一定为null, 1870 //将p的右子树接到s的右子树,将s的右子树,接到p的右子树 1871 //将p的父节点改为s的父节点,将s的父节点改为p的父节点 1872 boolean c = s.red; s.red = p.red; p.red = c; // 1873 TreeNode<K,V> sr = s.right; 1874 TreeNode<K,V> pp = p.parent; 1875 if (s == pr) { // p是s的父节点,将p接到s的右子节点 1876 p.parent = s; 1877 s.right = p; 1878 }else {//p与s非父子节点 1879 TreeNode<K,V> sp = s.parent; 1880 if ((p.parent = sp) != null) { 1881 if (s == sp.left) 1882 sp.left = p; 1883 else 1884 sp.right = p; 1885 } 1886 //将p的右子节点接到s的右子节点 1887 if ((s.right = pr) != null) 1888 pr.parent = s; 1889 } 1890 p.left = null; 1891 if ((p.right = sr) != null) 1892 sr.parent = p; 1893 if ((s.left = pl) != null) 1894 pl.parent = s; 1895 if ((s.parent = pp) == null) 1896 root = s; 1897 else if (p == pp.left) 1898 pp.left = s; 1899 else 1900 pp.right = s; 1901 if (sr != null) 1902 replacement = sr; 1903 else 1904 replacement = p; 1905 } 1906 else if (pl != null) 1907 replacement = pl; 1908 else if (pr != null) 1909 replacement = pr; 1910 else 1911 replacement = p; 1912 //s和p交换后,p没有左子树,此时只需要删除p,并将p的右子树接到p父节点上即可 1913 //此时p的子树如果存在,将p的子树替代p的位置,将p移除 1914 if (replacement != p) { 1915 TreeNode<K,V> pp = replacement.parent = p.parent; 1916 if (pp == null) 1917 root = replacement; 1918 else if (p == pp.left) 1919 pp.left = replacement; 1920 else 1921 pp.right = replacement; 1922 p.left = p.right = p.parent = null; 1923 } 1924 //如果p的颜色为红色,则此删除未破坏结构,否则重新调整树 1925 TreeNode<K,V> r = p.red ? root : balanceDeletion(root, replacement); 1926 //如果代替p的就是p自己,则直接分离p与p的父节点的关联 1927 if (replacement == p) { // detach 1928 TreeNode<K,V> pp = p.parent; 1929 p.parent = null; 1930 if (pp != null) { 1931 if (p == pp.left) 1932 pp.left = null; 1933 else if (p == pp.right) 1934 pp.right = null; 1935 } 1936 } 1937 //此参数仅当使用迭代器删除时,为false 1938 if (movable) 1939 moveRootToFront(tab, r); 1940 } 1941 1942 /** 1943 * 将树仓中的节点分解为上下树仓,如果现在太小,则将树仓拆成树仓。仅从调整大小调用;参见上面关于分裂位和索引的讨论。 1944 * 1945 * @param map the map 1946 * @param tab the table for recording bin heads 1947 * @param index 表被拆分的索引 1948 * @param bit hash分割的目标点位 1949 */ 1950 final void split(HashMap<K,V> map, Node<K,V>[] tab, int index, int bit) { 1951 TreeNode<K,V> b = this; 1952 // 转入LO和HI列表,保存顺序 1953 //低位桶 目标桶位置与之前相同 1954 TreeNode<K,V> loHead = null, loTail = null; 1955 //高位桶 目标桶位置为之前的位置+bit 1956 TreeNode<K,V> hiHead = null, hiTail = null; 1957 int lc = 0, hc = 0; 1958 for (TreeNode<K,V> e = b, next; e != null; e = next) { 1959 next = (TreeNode<K,V>)e.next; 1960 e.next = null; 1961 //e的hash值,在最高位为为0 则目标桶的位置,与之前相同 1962 if ((e.hash & bit) == 0) { 1963 //如果e的前一个元素不存在, e为低位桶的桶顶 1964 if ((e.prev = loTail) == null) 1965 loHead = e; 1966 //否则将e接到桶尾 1967 else 1968 loTail.next = e; 1969 loTail = e; 1970 ++lc;//低位桶长度+1 1971 } 1972 //e的hash值,在最高位为为1 则目标桶的位置,等于之前的位置+bit 1973 else { 1974 //如果e的前一个元素不存在, e为高位桶的桶顶 1975 if ((e.prev = hiTail) == null) 1976 hiHead = e; 1977 //否则将e接到桶尾 1978 else 1979 hiTail.next = e; 1980 hiTail = e; 1981 ++hc;//高位桶长度+1 1982 } 1983 } 1984 //低位桶存在 1985 if (loHead != null) { 1986 //低位桶的长度达到非树化的临界值 1987 if (lc <= UNTREEIFY_THRESHOLD) 1988 //在目标位置将低位桶非树化 1989 tab[index] = loHead.untreeify(map); 1990 else { 1991 // 1992 tab[index] = loHead; 1993 if (hiHead != null) // 如果高位树为空,则全在低位树中, 本来就是树 1994 loHead.treeify(tab); 1995 } 1996 } 1997 //高位桶存在 1998 if (hiHead != null) { 1999 if (hc <= UNTREEIFY_THRESHOLD) 2000 tab[index + bit] = hiHead.untreeify(map); 2001 else { 2002 tab[index + bit] = hiHead; 2003 if (loHead != null) 2004 hiHead.treeify(tab); 2005 } 2006 } 2007 } 2008 2009 /*------------------------------------------------------------ */ 2010 // 红黑树方法,均适用于CLR 2011 2012 /** 2013 * 左旋 2014 * @param root 2015 * @param p 2016 * @return 2017 */ 2018 static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root, TreeNode<K,V> p) { 2019 TreeNode<K,V> r, pp, rl; 2020 if (p != null && (r = p.right) != null) { 2021 if ((rl = p.right = r.left) != null) 2022 rl.parent = p; 2023 if ((pp = r.parent = p.parent) == null) 2024 (root = r).red = false; 2025 else if (pp.left == p) 2026 pp.left = r; 2027 else 2028 pp.right = r; 2029 r.left = p; 2030 p.parent = r; 2031 } 2032 return root; 2033 } 2034 /** 2035 * 右旋 2036 * @param root 2037 * @param p 2038 * @return 2039 */ 2040 static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root, TreeNode<K,V> p) { 2041 TreeNode<K,V> l, pp, lr; 2042 if (p != null && (l = p.left) != null) { 2043 if ((lr = p.left = l.right) != null) 2044 lr.parent = p; 2045 if ((pp = l.parent = p.parent) == null) 2046 (root = l).red = false; 2047 else if (pp.right == p) 2048 pp.right = l; 2049 else 2050 pp.left = l; 2051 l.right = p; 2052 p.parent = l; 2053 } 2054 return root; 2055 } 2056 /** 2057 *平衡插入 调整红黑树结构 返回根节点 条件为: 2058 *条件1:红色节点不可连续 2059 *条件2:任一节点到叶子节点的任一线路,黑色节点数量相等 2060 *调整的具体操作为,每次新添加节点后,如果节点的父节点也为红色,则不满足条件1, 2061 *1:如果其父节点是其祖父节点的左子树 2062 * 2:如果其叔父节点也为红色,则其祖父节点一定为黑色,此时调整颜色,将祖父节点变为红色,父节点和叔父节点变为黑色,满足条件2, 2063 * 但此时祖父节点变为红色,不一定满足条件一,从上述步骤1开始重复 2064 * 2:如果其叔父节点为null(叔父节点一定不是黑色,因为不满足条件2),如果为 ‘\’这样的两个红色节点,则x>xp,通过对父节点左旋调整为‘/’, 2065 * 将x和xp中较大的一个当做xp,较小的一个变为x,此时有x<xp<xpp,三个x红,xp红,xpp黑节点,调整颜色为x红,xp黑,xpp红后 2066 * 对xpp右旋,变为黑色父节点以及2个红色子节点,此时满足条件1和条件2 2067 *1:如果其父节点是其祖父节点的右子树,同上,反方向操作 2068 * @param root 2069 * @param x 2070 * @return 2071 */ 2072 static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root, TreeNode<K,V> x) { 2073 //红黑树中,新插入的节点一定为红色 2074 x.red = true; 2075 for (TreeNode<K,V> xp, xpp, xppl, xppr;;) { 2076 //x为根节点后, 根节点为黑色,然后返回x 2077 if ((xp = x.parent) == null) { 2078 x.red = false; 2079 return x; 2080 } 2081 //如果x的父节点xp为黑色 ,则新插入的红色节点,不破坏结构 2082 // 或者 父节点为根节点,则不破坏结构,直接返回根节点 2083 else if (!xp.red || (xpp = xp.parent) == null) 2084 return root; 2085 //如果x的父节点为其祖父的左子节点 并且为红色 2086 if (xp == (xppl = xpp.left)) { 2087 //并且其叔父节点不等于空,并且为红色 则调整颜色 2088 if ((xppr = xpp.right) != null && xppr.red) { 2089 xppr.red = false;//叔父节点 红>黑 2090 xp.red = false;//父节点 红>黑 2091 xpp.red = true;//祖父节点 黑>红 2092 x = xpp; //祖父节点变为红色后,继续调整祖父节点 2093 } 2094 //叔父节点为空 一定不会为黑色,如果是黑色不满足条件2 2095 else { 2096 //如果当前节点为其父节点的右子节点,将父节点左旋 2097 if (x == xp.right) { 2098 root = rotateLeft(root, x = xp); 2099 //调整后重新赋值父节点和祖父节点 2100 xpp = (xp = x.parent) == null ? null : xp.parent; 2101 } 2102 if (xp != null) { 2103 //将父节点红>黑 2104 xp.red = false; 2105 if (xpp != null) { 2106 //祖父节点黑>红 2107 xpp.red = true; 2108 //祖父节点变为红色后,右旋 2109 root = rotateRight(root, xpp); 2110 } 2111 } 2112 } 2113 } 2114 //如果x的父节点为其祖父的右子节点 并且为红色 与以上操作相反 2115 else { 2116 if (xppl != null && xppl.red) { 2117 xppl.red = false; 2118 xp.red = false; 2119 xpp.red = true; 2120 x = xpp; 2121 } 2122 else { 2123 if (x == xp.left) { 2124 root = rotateRight(root, x = xp); 2125 xpp = (xp = x.parent) == null ? null : xp.parent; 2126 } 2127 if (xp != null) { 2128 xp.red = false; 2129 if (xpp != null) { 2130 xpp.red = true; 2131 root = rotateLeft(root, xpp); 2132 } 2133 } 2134 } 2135 } 2136 } 2137 } 2138 /** 2139 * 平衡删除 调整结构 2140 * @param root 2141 * @param x 删除节点后,节点的替代节点 2142 * @return 2143 */ 2144 static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root, TreeNode<K,V> x) { 2145 for (TreeNode<K,V> xp, xpl, xpr;;) { 2146 //如果x为空,或根节点 2147 if (x == null || x == root) 2148 return root; 2149 //如果x的父节点为空,为根节点,根节点必须为黑色 2150 else if ((xp = x.parent) == null) { 2151 x.red = false; 2152 return x; 2153 } 2154 //如果x为红色,修改为黑色即可 2155 else if (x.red) { 2156 x.red = false; 2157 return root; 2158 } 2159 //x为黑色,并且是其父节点xp的左子节点 2160 else if ((xpl = xp.left) == x) { 2161 //TODO 未完待续 2162 //如果兄弟节点为红色,将兄弟节点修改为黑色,将父节点修改为红色,然后左旋父节点,然后为‘/’x黑,xp红,xpr黑 2163 if ((xpr = xp.right) != null && xpr.red) { 2164 xpr.red = false; 2165 xp.red = true; 2166 root = rotateLeft(root, xp); 2167 xpr = (xp = x.parent) == null ? null : xp.right; 2168 } 2169 //如果x兄弟节点为空,此时xp为红色节点 2170 if (xpr == null) 2171 x = xp; 2172 else { 2173 TreeNode<K,V> sl = xpr.left, sr = xpr.right; 2174 if ((sr == null || !sr.red) && 2175 (sl == null || !sl.red)) { 2176 xpr.red = true; 2177 x = xp; 2178 } 2179 else { 2180 if (sr == null || !sr.red) { 2181 if (sl != null) 2182 sl.red = false; 2183 xpr.red = true; 2184 root = rotateRight(root, xpr); 2185 xpr = (xp = x.parent) == null ? 2186 null : xp.right; 2187 } 2188 if (xpr != null) { 2189 xpr.red = (xp == null) ? false : xp.red; 2190 if ((sr = xpr.right) != null) 2191 sr.red = false; 2192 } 2193 if (xp != null) { 2194 xp.red = false; 2195 root = rotateLeft(root, xp); 2196 } 2197 x = root; 2198 } 2199 } 2200 } 2201 //同上对称 2202 else { 2203 if (xpl != null && xpl.red) { 2204 xpl.red = false; 2205 xp.red = true; 2206 root = rotateRight(root, xp); 2207 xpl = (xp = x.parent) == null ? null : xp.left; 2208 } 2209 if (xpl == null) 2210 x = xp; 2211 else { 2212 TreeNode<K,V> sl = xpl.left, sr = xpl.right; 2213 if ((sl == null || !sl.red) && 2214 (sr == null || !sr.red)) { 2215 xpl.red = true; 2216 x = xp; 2217 } 2218 else { 2219 if (sl == null || !sl.red) { 2220 if (sr != null) 2221 sr.red = false; 2222 xpl.red = true; 2223 root = rotateLeft(root, xpl); 2224 xpl = (xp = x.parent) == null ? 2225 null : xp.left; 2226 } 2227 if (xpl != null) { 2228 xpl.red = (xp == null) ? false : xp.red; 2229 if ((sl = xpl.left) != null) 2230 sl.red = false; 2231 } 2232 if (xp != null) { 2233 xp.red = false; 2234 root = rotateRight(root, xp); 2235 } 2236 x = root; 2237 } 2238 } 2239 } 2240 } 2241 } 2242 2243 /** 2244 * 这一步是防御性的编程 2245 * 校验TreeNode对象是否满足红黑树和双链表的特性 2246 * 如果这个方法校验不通过:可能是因为用户编程失误,破坏了结构(例如:并发场景下);也可能是TreeNode的实现有问题(这个是理论上的以防万一); 2247 */ 2248 static <K,V> boolean checkInvariants(TreeNode<K,V> t) { 2249 TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right, 2250 tb = t.prev, tn = (TreeNode<K,V>)t.next; 2251 if (tb != null && tb.next != t) 2252 return false; 2253 if (tn != null && tn.prev != t) 2254 return false; 2255 if (tp != null && t != tp.left && t != tp.right) 2256 return false; 2257 if (tl != null && (tl.parent != t || tl.hash > t.hash)) 2258 return false; 2259 if (tr != null && (tr.parent != t || tr.hash < t.hash)) 2260 return false; 2261 if (t.red && tl != null && tl.red && tr != null && tr.red) 2262 return false; 2263 if (tl != null && !checkInvariants(tl)) 2264 return false; 2265 if (tr != null && !checkInvariants(tr)) 2266 return false; 2267 return true; 2268 } 2269 } 2270 2271 }