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 }

 

posted @ 2018-10-29 21:43  我是小明呀嘿  阅读(237)  评论(0编辑  收藏  举报