JDK源码分析系列_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 
  13 /*
  14 底层基于散列算法实现,散列算法分为散列再探测和拉链式,HashMap-->拉链式
  15 HashMap并不保证键值对的顺序,这意味着在进行某些操作后,键值对的顺序可能会发生变化。
  16 HashMap的key必须是immutable(String、Integer)的,key可以用自定义的对象,但是自实现的类必须重写equals
  17 和hashcode方法
  18 
  19 JDK1.8HashMap的优化:
  20 1.引入红黑树解决过长链表效率低的问题
  21 2.重写resize方法,移除了alternative hashing相关方法,避免重新计算键的hash
  22 
  23 哈希冲突的解决方法:
  24 1.开放定址法(线性探测再散列,二次探测再散列,伪随机探测再散列)
  25 2.再哈希法,就是在原hash函数的基础,再次执行hash算法
  26 3.链地址法,各种处理哈希碰撞的方法中,这种最简单
  27 4.建立一个公共溢出区
  28 
  29 HashMap的线程不安全体现在:
  30 1.多线程同时put添加元素会丢失元素
  31 2.多线程同时扩容会造成死循环
  32 
  33 HashMap与Hashtable的区别:
  34 1.HashMap线程不安全,Hashtable线程安全
  35 2.HashMap可以存null键null值(在计算哈希值时,null键哈希值为0),Hashtable不可以
  36 3.HashMap去掉了Hashtable中的contains方法,改为了containsKey和containsValue
  37 4.Hashtable继承自陈旧的Dictionary类,而HashMap是JDK1.2引进的Map的一个实现
  38 5.Hashtable中hash数组默认大小为11,扩容方式为old*2+1,HashMap中hash数组默认大小是16,扩容方式为old*2
  39 6.hash算法不一样,Hashtable是除留余数法,HashMap是h = key.hashCode()) ^ (h >>> 16,映射到数组为hash&(n-1)
  40 7.HashMap的迭代器(Iterator)是fail-fast迭代器,而Hashtable的enumerator迭代器不是fail-fast的
  41  */
  42 public class HashMap<K,V> extends AbstractMap<K,V>
  43     implements Map<K,V>, Cloneable, Serializable {
  44     private static final long serialVersionUID = 362498820763181265L;
  45     /*
  46     默认初始化容量为16,HashMap的容量必须是2的整次幂(一定是合数),这是一种
  47     非常规的设计,常规的设计是把桶的大小设计为素数,相对来说素数导致冲突的概率
  48     要小于合数。Hashtable初始化桶的大小为11,扩容机制为扩容前容量乘以2加1。
  49     HashMap这种非常规的设计主要是为了在取模和扩容时作优化,同时为了减少冲突
  50      */
  51     static final int DEFAULT_INITIAL_CAPACITY = 1 << 4;
  52     //最大容量为2^30
  53     static final int MAXIMUM_CAPACITY = 1 << 30;
  54     /*
  55     负载因子设置高虽然可以减少空间开销,但是会增加查询时间,
  56     默认负载因子0.75是在时间和空间成本上的tradeoff,负载因子可以大于1
  57      */
  58     static final float DEFAULT_LOAD_FACTOR = 0.75f;
  59     /*
  60     链表长度>=8,转换为红黑树。有人可能会有疑问,为什么到8才转换?主要是因为红黑树的平均查找长度是log(n),
  61     长度为8时,平均查找长度是3。如果继续使用链表,平均查找长度为8/2=4,这才有转换为树的必要。
  62     */
  63     static final int TREEIFY_THRESHOLD = 8;
  64     /*
  65     长度为6时,树转链表。中间有个差值的原因是防止链表和树频繁转换。假设8以上转为树,8以下转为链表,那么一个
  66     HashMap如果不停的插入删除,长度在8左右徘徊,就会不停的树转链表,链表转树,效率很低。
  67     */
  68     static final int UNTREEIFY_THRESHOLD = 6;
  69     //最小的红黑树容量为64
  70     static final int MIN_TREEIFY_CAPACITY = 64;
  71     //基础的桶节点(bin node)
  72     static class Node<K,V> implements Map.Entry<K,V> {
  73         final int hash;
  74         final K key;
  75         V value;
  76         Node<K,V> next;
  77 
  78         Node(int hash, K key, V value, Node<K,V> next) {
  79             this.hash = hash;
  80             this.key = key;
  81             this.value = value;
  82             this.next = next;
  83         }
  84 
  85         public final K getKey()        { return key; }
  86         public final V getValue()      { return value; }
  87         public final String toString() { return key + "=" + value; }
  88 
  89         public final int hashCode() {
  90             return Objects.hashCode(key) ^ Objects.hashCode(value);
  91     }
  92 
  93         public final V setValue(V newValue) {
  94             V oldValue = value;
  95             value = newValue;
  96             return oldValue;
  97         }
  98 
  99         public final boolean equals(Object o) {
 100             if (o == this)
 101                 return true;
 102             if (o instanceof Map.Entry) {
 103                 Map.Entry<?,?> e = (Map.Entry<?,?>)o;
 104                 if (Objects.equals(key, e.getKey()) &&
 105                     Objects.equals(value, e.getValue()))
 106                     return true;
 107             }
 108             return false;
 109         }
 110     }
 111     /* ---------------- Static utilities -------------- */
 112 
 113     /*
 114     扰动函数 很多人可能不理解为什么要和h>>>16作一次异或,下面给出详细的解释:
 115     由于散列值是int类型的,如果直接拿散列值作为下标访问HashMap主数组的话,考虑到32位有符号的int值的范围从
 116     -2147483648到214748364,前后加起来大概40亿的映射空间。那么问题来了,一个40亿长度的数组,内存是放不下
 117     的,所以这个散列值是不能拿过来直接用的,JDK中通过(n-1)&hash这样的操作得到访问数组的下标。(实际上这个操
 118     作在n为2的整次幂时就等于hash%n)这也解释了为什么HashMap的数组长度要取2的整次幂,因为这样(数组长度-1)正
 119     好相当于一个“低位掩码”,与的结果就是散列值的高位清零,只保留低位值用来作数组下标。以初始长度16为例,16-1
 120     =15。二进制表示为00000000 00000000 00000000 00001111,和某散列值作与运算,结果就是截取了最低的4位值。
 121         10101010 10010101 10001110 00100101
 122     &   00000000 00000000 00000000 00001111
 123     ---------------------------------------
 124         00000000 00000000 00000000 00000101 //高位全部清零,只保留末4位
 125     那么问题又来了,就算散列值分布的再分散,要是只取最后几位的话,碰撞也会很严重。这时和h>>>16作一次异或的价值
 126     就体现出来了。
 127     h=key.hashCode(): 1111 1111 1111 1111 1111 0000 1110 1010   //调用hashCode()
 128     ---------------------------------------------------------
 129                    h: 1111 1111 1111 1111 1111 0000 1110 1010
 130               h>>>16: 0000 0000 0000 0000 1111 1111 1111 1111   //计算hash
 131      hash=h^(h>>>16): 1111 1111 1111 1111 0000 1111 0001 0101
 132     ---------------------------------------------------------
 133           (n-1)&hash: 0000 0000 0000 0000 0000 0000 0000 1111
 134                       1111 1111 1111 1111 0000 1111 0001 0101   //计算下标
 135                       0000 0000 0000 0000 0000 0000 0000 0101=5
 136     ---------------------------------------------------------
 137     右移16位,正好是32位的一半,自己的高半区和低半区作异或,就是为了混合原始散列值的高位和低位,使混合后的低位掺
 138     杂了高位的部分特征,以此来提高低位的随机性,从而可以有效降低碰撞次数。
 139     */
 140     static final int hash(Object key) {
 141         int h;
 142         return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
 143     }
 144     /*
 145     通过反射机制判断对象x是否实现Comparable接口
 146     如果实现了Comparable,返回x的实际类型,否则返回null
 147     */
 148     static Class<?> comparableClassFor(Object x) {
 149         if (x instanceof Comparable) {
 150             Class<?> c; Type[] ts, as; Type t; ParameterizedType p;
 151             if ((c = x.getClass()) == String.class)
 152                 return c;
 153             if ((ts = c.getGenericInterfaces()) != null) {
 154                 for (int i = 0; i < ts.length; ++i) {
 155                     if (((t = ts[i]) instanceof ParameterizedType) &&
 156                         ((p = (ParameterizedType)t).getRawType() ==
 157                          Comparable.class) &&
 158                         (as = p.getActualTypeArguments()) != null &&
 159                         as.length == 1 && as[0] == c)
 160                         return c;
 161                 }
 162             }
 163         }
 164         return null;
 165     }
 166 
 167     @SuppressWarnings({"rawtypes","unchecked"})
 168     static int compareComparables(Class<?> kc, Object k, Object x) {
 169         return (x == null || x.getClass() != kc ? 0 :
 170                 ((Comparable)k).compareTo(x));
 171     }
 172     /*
 173     返回不小于cap的最小的2的整次幂
 174     假设cap = 5
 175     n = cap - 1 =  4 = 0 1 0 0
 176     n |= n >>> 1;    0 1 0 0 | 0 0 1 0 = 0 1 1 0 = 6
 177     n |= n >>> 2;    0 1 1 0 | 0 0 0 1 = 0 1 1 1 = 7
 178     n |= n >>> 4;    0 1 1 1 | 0 0 0 0 = 0 1 1 1 = 7
 179     n |= n >>> 8;    0 1 1 1 | 0 0 0 0 = 0 1 1 1 = 7
 180     n |= n >>> 16;   0 1 1 1 | 0 0 0 0 = 0 1 1 1 = 7
 181     return n + 1     7 + 1 = 8
 182     有人可能不理解为什么要对cap作-1的预处理,下面给出解释:
 183     假设cap=8(即cap一开始就是2的整次幂)如果没有cap-1处理的话
 184     n |= n >>> 1;    1 0 0 0 | 0 1 0 0 = 1 1 0 0 = 12
 185     n |= n >>> 2;    1 1 0 0 | 0 0 1 1 = 1 1 1 1 = 15
 186     n |= n >>> 4;    1 1 1 1 | 0 0 0 0 = 1 1 1 1 = 15
 187     n |= n >>> 8;    1 1 1 1 | 0 0 0 0 = 1 1 1 1 = 15
 188     n |= n >>> 16;   1 1 1 1 | 0 0 0 0 = 1 1 1 1 = 15
 189     return n + 1     15 + 1 = 16
 190     这样得到的容量就不是>=cap的最小2的整次幂值,造成内存空间浪费。
 191     如果作cap-1预处理的话就不会这样。
 192     n = cap - 1 =  7 = 0 1 1 1
 193     n |= n >>> 1;    0 1 1 1 | 0 0 1 1 = 0 1 1 1 = 7
 194     n |= n >>> 2;    0 1 1 1 | 0 0 0 1 = 0 1 1 1 = 7
 195     n |= n >>> 4;    0 1 1 1 | 0 0 0 0 = 0 1 1 1 = 7
 196     n |= n >>> 8;    0 1 1 1 | 0 0 0 0 = 0 1 1 1 = 7
 197     n |= n >>> 16;   0 1 1 1 | 0 0 0 0 = 0 1 1 1 = 7
 198     return n + 1     7 + 1 = 8
 199     */
 200     static final int tableSizeFor(int cap) {
 201         int n = cap - 1;
 202         n |= n >>> 1;
 203         n |= n >>> 2;
 204         n |= n >>> 4;
 205         n |= n >>> 8;
 206         n |= n >>> 16;
 207         return (n < 0) ? 1 : (n >= MAXIMUM_CAPACITY) ? MAXIMUM_CAPACITY : n + 1;
 208     }
 209     //实际数据的存储数组
 210     transient Node<K,V>[] table;
 211 
 212     transient Set<Map.Entry<K,V>> entrySet;
 213 
 214     transient int size;
 215 
 216     //fail-fast机制
 217     transient int modCount;
 218 
 219     //扩容阈值 threshold=capacity*loadFactor
 220     int threshold;
 221 
 222     final float loadFactor;
 223     /* ---------------- Public operations -------------- */
 224 
 225     //含参构造函数
 226     public HashMap(int initialCapacity, float loadFactor) {
 227         if (initialCapacity < 0)
 228             throw new IllegalArgumentException("Illegal initial capacity: " +
 229                                                initialCapacity);
 230         if (initialCapacity > MAXIMUM_CAPACITY)
 231             initialCapacity = MAXIMUM_CAPACITY;
 232         if (loadFactor <= 0 || Float.isNaN(loadFactor))
 233             throw new IllegalArgumentException("Illegal load factor: " +
 234                                                loadFactor);
 235         this.loadFactor = loadFactor;
 236         //这里的阈值并不是由threshold=capacity*loadFactor计算得到的
 237         this.threshold = tableSizeFor(initialCapacity);
 238     }
 239 
 240     public HashMap(int initialCapacity) {
 241         this(initialCapacity, DEFAULT_LOAD_FACTOR);
 242     }
 243 
 244     public HashMap() {
 245         this.loadFactor = DEFAULT_LOAD_FACTOR;
 246     }
 247 
 248     public HashMap(Map<? extends K, ? extends V> m) {
 249         this.loadFactor = DEFAULT_LOAD_FACTOR;
 250         putMapEntries(m, false);
 251     }
 252 
 253     final void putMapEntries(Map<? extends K, ? extends V> m, boolean evict) {
 254         int s = m.size();
 255         if (s > 0) {
 256             //判断table是否已经初始化
 257             if (table == null) {
 258                 float ft = ((float)s / loadFactor) + 1.0F;
 259                 int t = ((ft < (float)MAXIMUM_CAPACITY) ?
 260                          (int)ft : MAXIMUM_CAPACITY);
 261                 if (t > threshold)
 262                     threshold = tableSizeFor(t);
 263             }
 264             //已经初始化,且m元素个数>阈值,进行扩容
 265             else if (s > threshold)
 266                 resize();
 267             for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) {
 268                 K key = e.getKey();
 269                 V value = e.getValue();
 270                 putVal(hash(key), key, value, false, evict);
 271             }
 272         }
 273     }
 274 
 275     public int size() {
 276         return size;
 277     }
 278 
 279     public boolean isEmpty() {
 280         return size == 0;
 281     }
 282     /*
 283     返回key对应的value
 284     需要注意的是返回null并不一定代表key不存在,有可能对应的value就是null
 285     */
 286     public V get(Object key) {
 287         Node<K,V> e;
 288         return (e = getNode(hash(key), key)) == null ? null : e.value;
 289     }
 290     /*
 291     first=tab[(n-1)&hash]是hash对应bin的第一个元素
 292     (k=first.key)==key||(key!=null&&key.equals(k))表明HashMap的key可以为null
 293     */
 294     final Node<K,V> getNode(int hash, Object key) {
 295         Node<K,V>[] tab; Node<K,V> first, e; int n; K k;
 296         if ((tab = table) != null && (n = tab.length) > 0 &&
 297             (first = tab[(n - 1) & hash]) != null) {
 298             //判断hash对应bin的第一个元素是否为给定的key
 299             if (first.hash == hash &&
 300                 ((k = first.key) == key || (key != null && key.equals(k))))
 301                 return first;
 302             //如果hash对应bin有不止一个元素
 303             if ((e = first.next) != null) {
 304                 //红黑树
 305                 if (first instanceof TreeNode)
 306                     return ((TreeNode<K,V>)first).getTreeNode(hash, key);
 307                 //链表
 308                 do {
 309                     if (e.hash == hash &&
 310                         ((k = e.key) == key || (key != null && key.equals(k))))
 311                         return e;
 312                 } while ((e = e.next) != null);
 313             }
 314         }
 315         return null;
 316     }
 317     //返回null代表不存在对应的key
 318     public boolean containsKey(Object key) {
 319         return getNode(hash(key), key) != null;
 320     }
 321 
 322     public V put(K key, V value) {
 323         return putVal(hash(key), key, value, false, true);
 324     }
 325 
 326     final V putVal(int hash, K key, V value, boolean onlyIfAbsent,
 327                    boolean evict) {
 328         Node<K,V>[] tab; Node<K,V> p; int n, i;
 329         //判断数组是否为null或长度是否为0,是就扩容
 330         if ((tab = table) == null || (n = tab.length) == 0)
 331             n = (tab = resize()).length;
 332         //判断bin第一个元素是否为null,是就直接插入
 333         if ((p = tab[i = (n - 1) & hash]) == null)
 334             tab[i] = newNode(hash, key, value, null);
 335         else {
 336             Node<K,V> e; K k;
 337             //判断bin第一个元素的key是否和待插入key一样,是就直接覆盖
 338             if (p.hash == hash &&
 339                 ((k = p.key) == key || (key != null && key.equals(k))))
 340                 e = p;
 341             //判断bin是否为红黑树,是就直接在树中插入
 342             else if (p instanceof TreeNode)
 343                 e = ((TreeNode<K,V>)p).putTreeVal(this, tab, hash, key, value);
 344             else {
 345                 //遍历
 346                 for (int binCount = 0; ; ++binCount) {
 347                     if ((e = p.next) == null) {
 348                         p.next = newNode(hash, key, value, null);
 349                         if (binCount >= TREEIFY_THRESHOLD - 1)//-1 for 1st
 350                             treeifyBin(tab, hash);
 351                         break;
 352                     }
 353                     if (e.hash == hash &&
 354                         ((k = e.key) == key || (key != null && key.equals(k))))
 355                         break;
 356                     p = e;
 357                 }
 358             }
 359             if (e != null) {
 360                 V oldValue = e.value;
 361                 if (!onlyIfAbsent || oldValue == null)
 362                     e.value = value;
 363                 afterNodeAccess(e);
 364                 return oldValue;
 365             }
 366         }
 367         ++modCount;
 368         if (++size > threshold)
 369             resize();
 370         afterNodeInsertion(evict);
 371         return null;
 372     }
 373 
 374 
 375     final Node<K,V>[] resize() {
 376         //给存储数组table起别名oldTab
 377         Node<K,V>[] oldTab = table;
 378         //得到扩容前的数组容量和扩容阈值
 379         int oldCap = (oldTab == null) ? 0 : oldTab.length;
 380         int oldThr = threshold;
 381         //定义新的数组容量和扩容阈值
 382         int newCap, newThr = 0;
 383 
 384         if (oldCap > 0) {
 385             //到达极限容量,无法扩容
 386             if (oldCap >= MAXIMUM_CAPACITY) {
 387                 /*
 388                 直接把扩容阈值置为Integer.MAX_VALUE即
 389                 32位hashcode的最大值,以免再次触发resize
 390                  */
 391                 threshold = Integer.MAX_VALUE;
 392                 return oldTab;
 393             }
 394             //扩容后的新的数组容量为原来的2倍
 395             else if ((newCap = oldCap << 1) < MAXIMUM_CAPACITY &&
 396                      oldCap >= DEFAULT_INITIAL_CAPACITY)
 397                 //负载因子不变,新的扩容阈值一定也是原来的2倍
 398                 newThr = oldThr << 1;
 399         }
 400         else if (oldThr > 0)// initial capacity was placed in threshold
 401             newCap = oldThr;
 402         else {              // zero initial threshold signifies using defaults
 403             newCap = DEFAULT_INITIAL_CAPACITY;
 404             newThr = (int)(DEFAULT_LOAD_FACTOR * DEFAULT_INITIAL_CAPACITY);
 405         }
 406         if (newThr == 0) {
 407             float ft = (float)newCap * loadFactor;
 408             newThr = (newCap < MAXIMUM_CAPACITY && ft < (float)MAXIMUM_CAPACITY ?
 409                       (int)ft : Integer.MAX_VALUE);
 410         }
 411         threshold = newThr;
 412         @SuppressWarnings({"rawtypes","unchecked"})
 413             //创建容量为newCap的newTab
 414             Node<K,V>[] newTab = (Node<K,V>[])new Node[newCap];
 415         table = newTab;
 416         if (oldTab != null) {
 417             for (int j = 0; j < oldCap; ++j) {
 418                 Node<K,V> e;
 419                 if ((e = oldTab[j]) != null) {
 420                     oldTab[j] = null;
 421                     if (e.next == null)
 422                         //e是bucket中唯一的一个元素,则直接赋值到newTab
 423                         newTab[e.hash & (newCap - 1)] = e;
 424                     else if (e instanceof TreeNode)
 425                         ((TreeNode<K,V>)e).split(this, newTab, j, oldCap);
 426                     else {
 427                         Node<K,V> loHead = null, loTail = null;
 428                         Node<K,V> hiHead = null, hiTail = null;
 429                         Node<K,V> next;
 430                         do {
 431                             next = e.next;
 432                             if ((e.hash & oldCap) == 0) {
 433                                 if (loTail == null)
 434                                     loHead = e;
 435                                 else
 436                                     loTail.next = e;
 437                                 loTail = e;
 438                             }
 439                             else {
 440                                 if (hiTail == null)
 441                                     hiHead = e;
 442                                 else
 443                                     hiTail.next = e;
 444                                 hiTail = e;
 445                             }
 446                         } while ((e = next) != null);
 447                         if (loTail != null) {
 448                             loTail.next = null;
 449                             newTab[j] = loHead;
 450                         }
 451                         if (hiTail != null) {
 452                             hiTail.next = null;
 453                             newTab[j + oldCap] = hiHead;
 454                         }
 455                     }
 456                 }
 457             }
 458         }
 459         return newTab;
 460     }
 461 
 462     final void treeifyBin(Node<K,V>[] tab, int hash) {
 463         int n, index; Node<K,V> e;
 464         if (tab == null || (n = tab.length) < MIN_TREEIFY_CAPACITY)
 465             resize();
 466         else if ((e = tab[index = (n - 1) & hash]) != null) {
 467             TreeNode<K,V> hd = null, tl = null;
 468             do {
 469                 TreeNode<K,V> p = replacementTreeNode(e, null);
 470                 if (tl == null)
 471                     hd = p;
 472                 else {
 473                     p.prev = tl;
 474                     tl.next = p;
 475                 }
 476                 tl = p;
 477             } while ((e = e.next) != null);
 478             if ((tab[index] = hd) != null)
 479                 hd.treeify(tab);
 480         }
 481     }
 482 
 483     public void putAll(Map<? extends K, ? extends V> m) {
 484         putMapEntries(m, true);
 485     }
 486 
 487     public V remove(Object key) {
 488         Node<K,V> e;
 489         return (e = removeNode(hash(key), key, null, false, true)) == null ?
 490             null : e.value;
 491     }
 492 
 493     final Node<K,V> removeNode(int hash, Object key, Object value,
 494                                boolean matchValue, boolean movable) {
 495         Node<K,V>[] tab; Node<K,V> p; int n, index;
 496         if ((tab = table) != null && (n = tab.length) > 0 &&
 497             (p = tab[index = (n - 1) & hash]) != null) {
 498             Node<K,V> node = null, e; K k; V v;
 499             if (p.hash == hash &&
 500                 ((k = p.key) == key || (key != null && key.equals(k))))
 501                 node = p;
 502             else if ((e = p.next) != null) {
 503                 if (p instanceof TreeNode)
 504                     node = ((TreeNode<K,V>)p).getTreeNode(hash, key);
 505                 else {
 506                     do {
 507                         if (e.hash == hash &&
 508                             ((k = e.key) == key ||
 509                              (key != null && key.equals(k)))) {
 510                             node = e;
 511                             break;
 512                         }
 513                         p = e;
 514                     } while ((e = e.next) != null);
 515                 }
 516             }
 517             if (node != null && (!matchValue || (v = node.value) == value ||
 518                                  (value != null && value.equals(v)))) {
 519                 if (node instanceof TreeNode)
 520                     ((TreeNode<K,V>)node).removeTreeNode(this, tab, movable);
 521                 else if (node == p)
 522                     tab[index] = node.next;
 523                 else
 524                     p.next = node.next;
 525                 ++modCount;
 526                 --size;
 527                 afterNodeRemoval(node);
 528                 return node;
 529             }
 530         }
 531         return null;
 532     }
 533 
 534     public void clear() {
 535         Node<K,V>[] tab;
 536         modCount++;
 537         if ((tab = table) != null && size > 0) {
 538             size = 0;
 539             for (int i = 0; i < tab.length; ++i)
 540                 tab[i] = null;
 541         }
 542     }
 543 
 544     public boolean containsValue(Object value) {
 545         Node<K,V>[] tab; V v;
 546         if ((tab = table) != null && size > 0) {
 547             for (int i = 0; i < tab.length; ++i) {
 548                 for (Node<K,V> e = tab[i]; e != null; e = e.next) {
 549                     if ((v = e.value) == value ||
 550                         (value != null && value.equals(v)))
 551                         return true;
 552                 }
 553             }
 554         }
 555         return false;
 556     }
 557 
 558     public Set<K> keySet() {
 559         Set<K> ks = keySet;
 560         if (ks == null) {
 561             ks = new KeySet();
 562             keySet = ks;
 563         }
 564         return ks;
 565     }
 566 
 567     final class KeySet extends AbstractSet<K> {
 568         public final int size()                 { return size; }
 569         public final void clear()               { HashMap.this.clear(); }
 570         public final Iterator<K> iterator()     { return new KeyIterator(); }
 571         public final boolean contains(Object o) { return containsKey(o); }
 572         public final boolean remove(Object key) {
 573             return removeNode(hash(key), key, null, false, true) != null;
 574         }
 575         public final Spliterator<K> spliterator() {
 576             return new KeySpliterator<>(HashMap.this, 0, -1, 0, 0);
 577         }
 578         public final void forEach(Consumer<? super K> action) {
 579             Node<K,V>[] tab;
 580             if (action == null)
 581                 throw new NullPointerException();
 582             if (size > 0 && (tab = table) != null) {
 583                 int mc = modCount;
 584                 for (int i = 0; i < tab.length; ++i) {
 585                     for (Node<K,V> e = tab[i]; e != null; e = e.next)
 586                         action.accept(e.key);
 587                 }
 588                 if (modCount != mc)
 589                     throw new ConcurrentModificationException();
 590             }
 591         }
 592     }
 593 
 594     public Collection<V> values() {
 595         Collection<V> vs = values;
 596         if (vs == null) {
 597             vs = new Values();
 598             values = vs;
 599         }
 600         return vs;
 601     }
 602 
 603     final class Values extends AbstractCollection<V> {
 604         public final int size()                 { return size; }
 605         public final void clear()               { HashMap.this.clear(); }
 606         public final Iterator<V> iterator()     { return new ValueIterator(); }
 607         public final boolean contains(Object o) { return containsValue(o); }
 608         public final Spliterator<V> spliterator() {
 609             return new ValueSpliterator<>(HashMap.this, 0, -1, 0, 0);
 610         }
 611         public final void forEach(Consumer<? super V> action) {
 612             Node<K,V>[] tab;
 613             if (action == null)
 614                 throw new NullPointerException();
 615             if (size > 0 && (tab = table) != null) {
 616                 int mc = modCount;
 617                 for (int i = 0; i < tab.length; ++i) {
 618                     for (Node<K,V> e = tab[i]; e != null; e = e.next)
 619                         action.accept(e.value);
 620                 }
 621                 if (modCount != mc)
 622                     throw new ConcurrentModificationException();
 623             }
 624         }
 625     }
 626 
 627     public Set<Map.Entry<K,V>> entrySet() {
 628         Set<Map.Entry<K,V>> es;
 629         return (es = entrySet) == null ? (entrySet = new EntrySet()) : es;
 630     }
 631 
 632     final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
 633         public final int size()                 { return size; }
 634         public final void clear()               { HashMap.this.clear(); }
 635         public final Iterator<Map.Entry<K,V>> iterator() {
 636             return new EntryIterator();
 637         }
 638         public final boolean contains(Object o) {
 639             if (!(o instanceof Map.Entry))
 640                 return false;
 641             Map.Entry<?,?> e = (Map.Entry<?,?>) o;
 642             Object key = e.getKey();
 643             Node<K,V> candidate = getNode(hash(key), key);
 644             return candidate != null && candidate.equals(e);
 645         }
 646         public final boolean remove(Object o) {
 647             if (o instanceof Map.Entry) {
 648                 Map.Entry<?,?> e = (Map.Entry<?,?>) o;
 649                 Object key = e.getKey();
 650                 Object value = e.getValue();
 651                 return removeNode(hash(key), key, value, true, true) != null;
 652             }
 653             return false;
 654         }
 655         public final Spliterator<Map.Entry<K,V>> spliterator() {
 656             return new EntrySpliterator<>(HashMap.this, 0, -1, 0, 0);
 657         }
 658         public final void forEach(Consumer<? super Map.Entry<K,V>> action) {
 659             Node<K,V>[] tab;
 660             if (action == null)
 661                 throw new NullPointerException();
 662             if (size > 0 && (tab = table) != null) {
 663                 int mc = modCount;
 664                 for (int i = 0; i < tab.length; ++i) {
 665                     for (Node<K,V> e = tab[i]; e != null; e = e.next)
 666                         action.accept(e);
 667                 }
 668                 if (modCount != mc)
 669                     throw new ConcurrentModificationException();
 670             }
 671         }
 672     }
 673 
 674     @Override
 675     public V getOrDefault(Object key, V defaultValue) {
 676         Node<K,V> e;
 677         return (e = getNode(hash(key), key)) == null ? defaultValue : e.value;
 678     }
 679 
 680     @Override
 681     public V putIfAbsent(K key, V value) {
 682         return putVal(hash(key), key, value, true, true);
 683     }
 684 
 685     @Override
 686     public boolean remove(Object key, Object value) {
 687         return removeNode(hash(key), key, value, true, true) != null;
 688     }
 689 
 690     @Override
 691     public boolean replace(K key, V oldValue, V newValue) {
 692         Node<K,V> e; V v;
 693         if ((e = getNode(hash(key), key)) != null &&
 694             ((v = e.value) == oldValue || (v != null && v.equals(oldValue)))) {
 695             e.value = newValue;
 696             afterNodeAccess(e);
 697             return true;
 698         }
 699         return false;
 700     }
 701 
 702     @Override
 703     public V replace(K key, V value) {
 704         Node<K,V> e;
 705         if ((e = getNode(hash(key), key)) != null) {
 706             V oldValue = e.value;
 707             e.value = value;
 708             afterNodeAccess(e);
 709             return oldValue;
 710         }
 711         return null;
 712     }
 713 
 714     @Override
 715     public V computeIfAbsent(K key,
 716                              Function<? super K, ? extends V> mappingFunction) {
 717         if (mappingFunction == null)
 718             throw new NullPointerException();
 719         int hash = hash(key);
 720         Node<K,V>[] tab; Node<K,V> first; int n, i;
 721         int binCount = 0;
 722         TreeNode<K,V> t = null;
 723         Node<K,V> old = null;
 724         if (size > threshold || (tab = table) == null ||
 725             (n = tab.length) == 0)
 726             n = (tab = resize()).length;
 727         if ((first = tab[i = (n - 1) & hash]) != null) {
 728             if (first instanceof TreeNode)
 729                 old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key);
 730             else {
 731                 Node<K,V> e = first; K k;
 732                 do {
 733                     if (e.hash == hash &&
 734                         ((k = e.key) == key || (key != null && key.equals(k)))) {
 735                         old = e;
 736                         break;
 737                     }
 738                     ++binCount;
 739                 } while ((e = e.next) != null);
 740             }
 741             V oldValue;
 742             if (old != null && (oldValue = old.value) != null) {
 743                 afterNodeAccess(old);
 744                 return oldValue;
 745             }
 746         }
 747         V v = mappingFunction.apply(key);
 748         if (v == null) {
 749             return null;
 750         } else if (old != null) {
 751             old.value = v;
 752             afterNodeAccess(old);
 753             return v;
 754         }
 755         else if (t != null)
 756             t.putTreeVal(this, tab, hash, key, v);
 757         else {
 758             tab[i] = newNode(hash, key, v, first);
 759             if (binCount >= TREEIFY_THRESHOLD - 1)
 760                 treeifyBin(tab, hash);
 761         }
 762         ++modCount;
 763         ++size;
 764         afterNodeInsertion(true);
 765         return v;
 766     }
 767 
 768     public V computeIfPresent(K key,
 769                               BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
 770         if (remappingFunction == null)
 771             throw new NullPointerException();
 772         Node<K,V> e; V oldValue;
 773         int hash = hash(key);
 774         if ((e = getNode(hash, key)) != null &&
 775             (oldValue = e.value) != null) {
 776             V v = remappingFunction.apply(key, oldValue);
 777             if (v != null) {
 778                 e.value = v;
 779                 afterNodeAccess(e);
 780                 return v;
 781             }
 782             else
 783                 removeNode(hash, key, null, false, true);
 784         }
 785         return null;
 786     }
 787 
 788     @Override
 789     public V compute(K key,
 790                      BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
 791         if (remappingFunction == null)
 792             throw new NullPointerException();
 793         int hash = hash(key);
 794         Node<K,V>[] tab; Node<K,V> first; int n, i;
 795         int binCount = 0;
 796         TreeNode<K,V> t = null;
 797         Node<K,V> old = null;
 798         if (size > threshold || (tab = table) == null ||
 799             (n = tab.length) == 0)
 800             n = (tab = resize()).length;
 801         if ((first = tab[i = (n - 1) & hash]) != null) {
 802             if (first instanceof TreeNode)
 803                 old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key);
 804             else {
 805                 Node<K,V> e = first; K k;
 806                 do {
 807                     if (e.hash == hash &&
 808                         ((k = e.key) == key || (key != null && key.equals(k)))) {
 809                         old = e;
 810                         break;
 811                     }
 812                     ++binCount;
 813                 } while ((e = e.next) != null);
 814             }
 815         }
 816         V oldValue = (old == null) ? null : old.value;
 817         V v = remappingFunction.apply(key, oldValue);
 818         if (old != null) {
 819             if (v != null) {
 820                 old.value = v;
 821                 afterNodeAccess(old);
 822             }
 823             else
 824                 removeNode(hash, key, null, false, true);
 825         }
 826         else if (v != null) {
 827             if (t != null)
 828                 t.putTreeVal(this, tab, hash, key, v);
 829             else {
 830                 tab[i] = newNode(hash, key, v, first);
 831                 if (binCount >= TREEIFY_THRESHOLD - 1)
 832                     treeifyBin(tab, hash);
 833             }
 834             ++modCount;
 835             ++size;
 836             afterNodeInsertion(true);
 837         }
 838         return v;
 839     }
 840 
 841     @Override
 842     public V merge(K key, V value,
 843                    BiFunction<? super V, ? super V, ? extends V> remappingFunction) {
 844         if (value == null)
 845             throw new NullPointerException();
 846         if (remappingFunction == null)
 847             throw new NullPointerException();
 848         int hash = hash(key);
 849         Node<K,V>[] tab; Node<K,V> first; int n, i;
 850         int binCount = 0;
 851         TreeNode<K,V> t = null;
 852         Node<K,V> old = null;
 853         if (size > threshold || (tab = table) == null ||
 854             (n = tab.length) == 0)
 855             n = (tab = resize()).length;
 856         if ((first = tab[i = (n - 1) & hash]) != null) {
 857             if (first instanceof TreeNode)
 858                 old = (t = (TreeNode<K,V>)first).getTreeNode(hash, key);
 859             else {
 860                 Node<K,V> e = first; K k;
 861                 do {
 862                     if (e.hash == hash &&
 863                         ((k = e.key) == key || (key != null && key.equals(k)))) {
 864                         old = e;
 865                         break;
 866                     }
 867                     ++binCount;
 868                 } while ((e = e.next) != null);
 869             }
 870         }
 871         if (old != null) {
 872             V v;
 873             if (old.value != null)
 874                 v = remappingFunction.apply(old.value, value);
 875             else
 876                 v = value;
 877             if (v != null) {
 878                 old.value = v;
 879                 afterNodeAccess(old);
 880             }
 881             else
 882                 removeNode(hash, key, null, false, true);
 883             return v;
 884         }
 885         if (value != null) {
 886             if (t != null)
 887                 t.putTreeVal(this, tab, hash, key, value);
 888             else {
 889                 tab[i] = newNode(hash, key, value, first);
 890                 if (binCount >= TREEIFY_THRESHOLD - 1)
 891                     treeifyBin(tab, hash);
 892             }
 893             ++modCount;
 894             ++size;
 895             afterNodeInsertion(true);
 896         }
 897         return value;
 898     }
 899 
 900     @Override
 901     public void forEach(BiConsumer<? super K, ? super V> action) {
 902         Node<K,V>[] tab;
 903         if (action == null)
 904             throw new NullPointerException();
 905         if (size > 0 && (tab = table) != null) {
 906             int mc = modCount;
 907             for (int i = 0; i < tab.length; ++i) {
 908                 for (Node<K,V> e = tab[i]; e != null; e = e.next)
 909                     action.accept(e.key, e.value);
 910             }
 911             if (modCount != mc)
 912                 throw new ConcurrentModificationException();
 913         }
 914     }
 915 
 916     @Override
 917     public void replaceAll(BiFunction<? super K, ? super V, ? extends V> function) {
 918         Node<K,V>[] tab;
 919         if (function == null)
 920             throw new NullPointerException();
 921         if (size > 0 && (tab = table) != null) {
 922             int mc = modCount;
 923             for (int i = 0; i < tab.length; ++i) {
 924                 for (Node<K,V> e = tab[i]; e != null; e = e.next) {
 925                     e.value = function.apply(e.key, e.value);
 926                 }
 927             }
 928             if (modCount != mc)
 929                 throw new ConcurrentModificationException();
 930         }
 931     }
 932     /* ---------------- Cloning and serialization -------------- */
 933 
 934     @SuppressWarnings("unchecked")
 935     @Override
 936     public Object clone() {
 937         HashMap<K,V> result;
 938         try {
 939             result = (HashMap<K,V>)super.clone();
 940         } catch (CloneNotSupportedException e) {
 941             throw new InternalError(e);
 942         }
 943         result.reinitialize();
 944         result.putMapEntries(this, false);
 945         return result;
 946     }
 947 
 948     final float loadFactor() { return loadFactor; }
 949     final int capacity() {
 950         return (table != null) ? table.length :
 951             (threshold > 0) ? threshold :
 952             DEFAULT_INITIAL_CAPACITY;
 953     }
 954 
 955     private void writeObject(java.io.ObjectOutputStream s)
 956         throws IOException {
 957         int buckets = capacity();
 958         s.defaultWriteObject();
 959         s.writeInt(buckets);
 960         s.writeInt(size);
 961         internalWriteEntries(s);
 962     }
 963 
 964     private void readObject(java.io.ObjectInputStream s)
 965         throws IOException, ClassNotFoundException {
 966         s.defaultReadObject();
 967         reinitialize();
 968         if (loadFactor <= 0 || Float.isNaN(loadFactor))
 969             throw new InvalidObjectException("Illegal load factor: " +
 970                                              loadFactor);
 971         s.readInt();
 972         int mappings = s.readInt();
 973         if (mappings < 0)
 974             throw new InvalidObjectException("Illegal mappings count: " +
 975                                              mappings);
 976         else if (mappings > 0) {
 977             float lf = Math.min(Math.max(0.25f, loadFactor), 4.0f);
 978             float fc = (float)mappings / lf + 1.0f;
 979             int cap = ((fc < DEFAULT_INITIAL_CAPACITY) ?
 980                        DEFAULT_INITIAL_CAPACITY :
 981                        (fc >= MAXIMUM_CAPACITY) ?
 982                        MAXIMUM_CAPACITY :
 983                        tableSizeFor((int)fc));
 984             float ft = (float)cap * lf;
 985             threshold = ((cap < MAXIMUM_CAPACITY && ft < MAXIMUM_CAPACITY) ?
 986                          (int)ft : Integer.MAX_VALUE);
 987             @SuppressWarnings({"rawtypes","unchecked"})
 988                 Node<K,V>[] tab = (Node<K,V>[])new Node[cap];
 989             table = tab;
 990 
 991             for (int i = 0; i < mappings; i++) {
 992                 @SuppressWarnings("unchecked")
 993                     K key = (K) s.readObject();
 994                 @SuppressWarnings("unchecked")
 995                     V value = (V) s.readObject();
 996                 putVal(hash(key), key, value, false, false);
 997             }
 998         }
 999     }
1000 
1001     /* ---------------- iterators -------------- */
1002 
1003     abstract class HashIterator {
1004         Node<K,V> next;
1005         Node<K,V> current;
1006         int expectedModCount;
1007         int index;
1008 
1009         HashIterator() {
1010             expectedModCount = modCount;
1011             Node<K,V>[] t = table;
1012             current = next = null;
1013             index = 0;
1014             if (t != null && size > 0) {
1015                 do {} while (index < t.length && (next = t[index++]) == null);
1016             }
1017         }
1018 
1019         public final boolean hasNext() {
1020             return next != null;
1021         }
1022 
1023         final Node<K,V> nextNode() {
1024             Node<K,V>[] t;
1025             Node<K,V> e = next;
1026             if (modCount != expectedModCount)
1027                 throw new ConcurrentModificationException();
1028             if (e == null)
1029                 throw new NoSuchElementException();
1030             if ((next = (current = e).next) == null && (t = table) != null) {
1031                 do {} while (index < t.length && (next = t[index++]) == null);
1032             }
1033             return e;
1034         }
1035 
1036         public final void remove() {
1037             Node<K,V> p = current;
1038             if (p == null)
1039                 throw new IllegalStateException();
1040             if (modCount != expectedModCount)
1041                 throw new ConcurrentModificationException();
1042             current = null;
1043             K key = p.key;
1044             removeNode(hash(key), key, null, false, false);
1045             expectedModCount = modCount;
1046         }
1047     }
1048 
1049     final class KeyIterator extends HashIterator
1050         implements Iterator<K> {
1051         public final K next() { return nextNode().key; }
1052     }
1053 
1054     final class ValueIterator extends HashIterator
1055         implements Iterator<V> {
1056         public final V next() { return nextNode().value; }
1057     }
1058 
1059     final class EntryIterator extends HashIterator
1060         implements Iterator<Map.Entry<K,V>> {
1061         public final Map.Entry<K,V> next() { return nextNode(); }
1062     }
1063 
1064     /* ---------------- spliterators -------------- */
1065 
1066     static class HashMapSpliterator<K,V> {
1067         final HashMap<K,V> map;
1068         Node<K,V> current;
1069         int index;
1070         int fence;
1071         int est;
1072         int expectedModCount;
1073 
1074         HashMapSpliterator(HashMap<K,V> m, int origin,
1075                            int fence, int est,
1076                            int expectedModCount) {
1077             this.map = m;
1078             this.index = origin;
1079             this.fence = fence;
1080             this.est = est;
1081             this.expectedModCount = expectedModCount;
1082         }
1083 
1084         final int getFence() {
1085             int hi;
1086             if ((hi = fence) < 0) {
1087                 HashMap<K,V> m = map;
1088                 est = m.size;
1089                 expectedModCount = m.modCount;
1090                 Node<K,V>[] tab = m.table;
1091                 hi = fence = (tab == null) ? 0 : tab.length;
1092             }
1093             return hi;
1094         }
1095 
1096         public final long estimateSize() {
1097             getFence();
1098             return (long) est;
1099         }
1100     }
1101 
1102     static final class KeySpliterator<K,V>
1103         extends HashMapSpliterator<K,V>
1104         implements Spliterator<K> {
1105         KeySpliterator(HashMap<K,V> m, int origin, int fence, int est,
1106                        int expectedModCount) {
1107             super(m, origin, fence, est, expectedModCount);
1108         }
1109 
1110         public KeySpliterator<K,V> trySplit() {
1111             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
1112             return (lo >= mid || current != null) ? null :
1113                 new KeySpliterator<>(map, lo, index = mid, est >>>= 1,
1114                                         expectedModCount);
1115         }
1116 
1117         public void forEachRemaining(Consumer<? super K> action) {
1118             int i, hi, mc;
1119             if (action == null)
1120                 throw new NullPointerException();
1121             HashMap<K,V> m = map;
1122             Node<K,V>[] tab = m.table;
1123             if ((hi = fence) < 0) {
1124                 mc = expectedModCount = m.modCount;
1125                 hi = fence = (tab == null) ? 0 : tab.length;
1126             }
1127             else
1128                 mc = expectedModCount;
1129             if (tab != null && tab.length >= hi &&
1130                 (i = index) >= 0 && (i < (index = hi) || current != null)) {
1131                 Node<K,V> p = current;
1132                 current = null;
1133                 do {
1134                     if (p == null)
1135                         p = tab[i++];
1136                     else {
1137                         action.accept(p.key);
1138                         p = p.next;
1139                     }
1140                 } while (p != null || i < hi);
1141                 if (m.modCount != mc)
1142                     throw new ConcurrentModificationException();
1143             }
1144         }
1145 
1146         public boolean tryAdvance(Consumer<? super K> action) {
1147             int hi;
1148             if (action == null)
1149                 throw new NullPointerException();
1150             Node<K,V>[] tab = map.table;
1151             if (tab != null && tab.length >= (hi = getFence()) && index >= 0) {
1152                 while (current != null || index < hi) {
1153                     if (current == null)
1154                         current = tab[index++];
1155                     else {
1156                         K k = current.key;
1157                         current = current.next;
1158                         action.accept(k);
1159                         if (map.modCount != expectedModCount)
1160                             throw new ConcurrentModificationException();
1161                         return true;
1162                     }
1163                 }
1164             }
1165             return false;
1166         }
1167 
1168         public int characteristics() {
1169             return (fence < 0 || est == map.size ? Spliterator.SIZED : 0) |
1170                 Spliterator.DISTINCT;
1171         }
1172     }
1173 
1174     static final class ValueSpliterator<K,V>
1175         extends HashMapSpliterator<K,V>
1176         implements Spliterator<V> {
1177         ValueSpliterator(HashMap<K,V> m, int origin, int fence, int est,
1178                          int expectedModCount) {
1179             super(m, origin, fence, est, expectedModCount);
1180         }
1181 
1182         public ValueSpliterator<K,V> trySplit() {
1183             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
1184             return (lo >= mid || current != null) ? null :
1185                 new ValueSpliterator<>(map, lo, index = mid, est >>>= 1,
1186                                           expectedModCount);
1187         }
1188 
1189         public void forEachRemaining(Consumer<? super V> action) {
1190             int i, hi, mc;
1191             if (action == null)
1192                 throw new NullPointerException();
1193             HashMap<K,V> m = map;
1194             Node<K,V>[] tab = m.table;
1195             if ((hi = fence) < 0) {
1196                 mc = expectedModCount = m.modCount;
1197                 hi = fence = (tab == null) ? 0 : tab.length;
1198             }
1199             else
1200                 mc = expectedModCount;
1201             if (tab != null && tab.length >= hi &&
1202                 (i = index) >= 0 && (i < (index = hi) || current != null)) {
1203                 Node<K,V> p = current;
1204                 current = null;
1205                 do {
1206                     if (p == null)
1207                         p = tab[i++];
1208                     else {
1209                         action.accept(p.value);
1210                         p = p.next;
1211                     }
1212                 } while (p != null || i < hi);
1213                 if (m.modCount != mc)
1214                     throw new ConcurrentModificationException();
1215             }
1216         }
1217 
1218         public boolean tryAdvance(Consumer<? super V> action) {
1219             int hi;
1220             if (action == null)
1221                 throw new NullPointerException();
1222             Node<K,V>[] tab = map.table;
1223             if (tab != null && tab.length >= (hi = getFence()) && index >= 0) {
1224                 while (current != null || index < hi) {
1225                     if (current == null)
1226                         current = tab[index++];
1227                     else {
1228                         V v = current.value;
1229                         current = current.next;
1230                         action.accept(v);
1231                         if (map.modCount != expectedModCount)
1232                             throw new ConcurrentModificationException();
1233                         return true;
1234                     }
1235                 }
1236             }
1237             return false;
1238         }
1239 
1240         public int characteristics() {
1241             return (fence < 0 || est == map.size ? Spliterator.SIZED : 0);
1242         }
1243     }
1244 
1245     static final class EntrySpliterator<K,V>
1246         extends HashMapSpliterator<K,V>
1247         implements Spliterator<Map.Entry<K,V>> {
1248         EntrySpliterator(HashMap<K,V> m, int origin, int fence, int est,
1249                          int expectedModCount) {
1250             super(m, origin, fence, est, expectedModCount);
1251         }
1252 
1253         public EntrySpliterator<K,V> trySplit() {
1254             int hi = getFence(), lo = index, mid = (lo + hi) >>> 1;
1255             return (lo >= mid || current != null) ? null :
1256                 new EntrySpliterator<>(map, lo, index = mid, est >>>= 1,
1257                                           expectedModCount);
1258         }
1259 
1260         public void forEachRemaining(Consumer<? super Map.Entry<K,V>> action) {
1261             int i, hi, mc;
1262             if (action == null)
1263                 throw new NullPointerException();
1264             HashMap<K,V> m = map;
1265             Node<K,V>[] tab = m.table;
1266             if ((hi = fence) < 0) {
1267                 mc = expectedModCount = m.modCount;
1268                 hi = fence = (tab == null) ? 0 : tab.length;
1269             }
1270             else
1271                 mc = expectedModCount;
1272             if (tab != null && tab.length >= hi &&
1273                 (i = index) >= 0 && (i < (index = hi) || current != null)) {
1274                 Node<K,V> p = current;
1275                 current = null;
1276                 do {
1277                     if (p == null)
1278                         p = tab[i++];
1279                     else {
1280                         action.accept(p);
1281                         p = p.next;
1282                     }
1283                 } while (p != null || i < hi);
1284                 if (m.modCount != mc)
1285                     throw new ConcurrentModificationException();
1286             }
1287         }
1288 
1289         public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) {
1290             int hi;
1291             if (action == null)
1292                 throw new NullPointerException();
1293             Node<K,V>[] tab = map.table;
1294             if (tab != null && tab.length >= (hi = getFence()) && index >= 0) {
1295                 while (current != null || index < hi) {
1296                     if (current == null)
1297                         current = tab[index++];
1298                     else {
1299                         Node<K,V> e = current;
1300                         current = current.next;
1301                         action.accept(e);
1302                         if (map.modCount != expectedModCount)
1303                             throw new ConcurrentModificationException();
1304                         return true;
1305                     }
1306                 }
1307             }
1308             return false;
1309         }
1310 
1311         public int characteristics() {
1312             return (fence < 0 || est == map.size ? Spliterator.SIZED : 0) |
1313                 Spliterator.DISTINCT;
1314         }
1315     }
1316 
1317     /* ---------------- LinkedHashMap support -------------- */
1318 
1319     Node<K,V> newNode(int hash, K key, V value, Node<K,V> next) {
1320         return new Node<>(hash, key, value, next);
1321     }
1322 
1323     Node<K,V> replacementNode(Node<K,V> p, Node<K,V> next) {
1324         return new Node<>(p.hash, p.key, p.value, next);
1325     }
1326 
1327     TreeNode<K,V> newTreeNode(int hash, K key, V value, Node<K,V> next) {
1328         return new TreeNode<>(hash, key, value, next);
1329     }
1330 
1331     TreeNode<K,V> replacementTreeNode(Node<K,V> p, Node<K,V> next) {
1332         return new TreeNode<>(p.hash, p.key, p.value, next);
1333     }
1334 
1335     void reinitialize() {
1336         table = null;
1337         entrySet = null;
1338         keySet = null;
1339         values = null;
1340         modCount = 0;
1341         threshold = 0;
1342         size = 0;
1343     }
1344 
1345     void afterNodeAccess(Node<K,V> p) { }
1346     void afterNodeInsertion(boolean evict) { }
1347     void afterNodeRemoval(Node<K,V> p) { }
1348 
1349     void internalWriteEntries(java.io.ObjectOutputStream s) throws IOException {
1350         Node<K,V>[] tab;
1351         if (size > 0 && (tab = table) != null) {
1352             for (int i = 0; i < tab.length; ++i) {
1353                 for (Node<K,V> e = tab[i]; e != null; e = e.next) {
1354                     s.writeObject(e.key);
1355                     s.writeObject(e.value);
1356                 }
1357             }
1358         }
1359     }
1360 
1361     /* ---------------- Tree bins -------------- */
1362 
1363     static final class TreeNode<K,V> extends LinkedHashMap.Entry<K,V> {
1364         TreeNode<K,V> parent;
1365         TreeNode<K,V> left;
1366         TreeNode<K,V> right;
1367         TreeNode<K,V> prev;
1368         boolean red;
1369         TreeNode(int hash, K key, V val, Node<K,V> next) {
1370             super(hash, key, val, next);
1371         }
1372 
1373         final TreeNode<K,V> root() {
1374             for (TreeNode<K,V> r = this, p;;) {
1375                 if ((p = r.parent) == null)
1376                     return r;
1377                 r = p;
1378             }
1379         }
1380 
1381         static <K,V> void moveRootToFront(Node<K,V>[] tab, TreeNode<K,V> root) {
1382             int n;
1383             if (root != null && tab != null && (n = tab.length) > 0) {
1384                 int index = (n - 1) & root.hash;
1385                 TreeNode<K,V> first = (TreeNode<K,V>)tab[index];
1386                 if (root != first) {
1387                     Node<K,V> rn;
1388                     tab[index] = root;
1389                     TreeNode<K,V> rp = root.prev;
1390                     if ((rn = root.next) != null)
1391                         ((TreeNode<K,V>)rn).prev = rp;
1392                     if (rp != null)
1393                         rp.next = rn;
1394                     if (first != null)
1395                         first.prev = root;
1396                     root.next = first;
1397                     root.prev = null;
1398                 }
1399                 assert checkInvariants(root);
1400             }
1401         }
1402 
1403         final TreeNode<K,V> find(int h, Object k, Class<?> kc) {
1404             TreeNode<K,V> p = this;
1405             do {
1406                 int ph, dir; K pk;
1407                 TreeNode<K,V> pl = p.left, pr = p.right, q;
1408                 if ((ph = p.hash) > h)
1409                     p = pl;
1410                 else if (ph < h)
1411                     p = pr;
1412                 else if ((pk = p.key) == k || (k != null && k.equals(pk)))
1413                     return p;
1414                 else if (pl == null)
1415                     p = pr;
1416                 else if (pr == null)
1417                     p = pl;
1418                 else if ((kc != null ||
1419                           (kc = comparableClassFor(k)) != null) &&
1420                          (dir = compareComparables(kc, k, pk)) != 0)
1421                     p = (dir < 0) ? pl : pr;
1422                 else if ((q = pr.find(h, k, kc)) != null)
1423                     return q;
1424                 else
1425                     p = pl;
1426             } while (p != null);
1427             return null;
1428         }
1429 
1430         final TreeNode<K,V> getTreeNode(int h, Object k) {
1431             return ((parent != null) ? root() : this).find(h, k, null);
1432         }
1433 
1434         static int tieBreakOrder(Object a, Object b) {
1435             int d;
1436             if (a == null || b == null ||
1437                 (d = a.getClass().getName().
1438                  compareTo(b.getClass().getName())) == 0)
1439                 d = (System.identityHashCode(a) <= System.identityHashCode(b) ?
1440                      -1 : 1);
1441             return d;
1442         }
1443 
1444         final void treeify(Node<K,V>[] tab) {
1445             TreeNode<K,V> root = null;
1446             for (TreeNode<K,V> x = this, next; x != null; x = next) {
1447                 next = (TreeNode<K,V>)x.next;
1448                 x.left = x.right = null;
1449                 if (root == null) {
1450                     x.parent = null;
1451                     x.red = false;
1452                     root = x;
1453                 }
1454                 else {
1455                     K k = x.key;
1456                     int h = x.hash;
1457                     Class<?> kc = null;
1458                     for (TreeNode<K,V> p = root;;) {
1459                         int dir, ph;
1460                         K pk = p.key;
1461                         if ((ph = p.hash) > h)
1462                             dir = -1;
1463                         else if (ph < h)
1464                             dir = 1;
1465                         else if ((kc == null &&
1466                                   (kc = comparableClassFor(k)) == null) ||
1467                                  (dir = compareComparables(kc, k, pk)) == 0)
1468                             dir = tieBreakOrder(k, pk);
1469 
1470                         TreeNode<K,V> xp = p;
1471                         if ((p = (dir <= 0) ? p.left : p.right) == null) {
1472                             x.parent = xp;
1473                             if (dir <= 0)
1474                                 xp.left = x;
1475                             else
1476                                 xp.right = x;
1477                             root = balanceInsertion(root, x);
1478                             break;
1479                         }
1480                     }
1481                 }
1482             }
1483             moveRootToFront(tab, root);
1484         }
1485 
1486         final Node<K,V> untreeify(HashMap<K,V> map) {
1487             Node<K,V> hd = null, tl = null;
1488             for (Node<K,V> q = this; q != null; q = q.next) {
1489                 Node<K,V> p = map.replacementNode(q, null);
1490                 if (tl == null)
1491                     hd = p;
1492                 else
1493                     tl.next = p;
1494                 tl = p;
1495             }
1496             return hd;
1497         }
1498 
1499         final TreeNode<K,V> putTreeVal(HashMap<K,V> map, Node<K,V>[] tab,
1500                                        int h, K k, V v) {
1501             Class<?> kc = null;
1502             boolean searched = false;
1503             TreeNode<K,V> root = (parent != null) ? root() : this;
1504             for (TreeNode<K,V> p = root;;) {
1505                 int dir, ph; K pk;
1506                 if ((ph = p.hash) > h)
1507                     dir = -1;
1508                 else if (ph < h)
1509                     dir = 1;
1510                 else if ((pk = p.key) == k || (k != null && k.equals(pk)))
1511                     return p;
1512                 else if ((kc == null &&
1513                           (kc = comparableClassFor(k)) == null) ||
1514                          (dir = compareComparables(kc, k, pk)) == 0) {
1515                     if (!searched) {
1516                         TreeNode<K,V> q, ch;
1517                         searched = true;
1518                         if (((ch = p.left) != null &&
1519                              (q = ch.find(h, k, kc)) != null) ||
1520                             ((ch = p.right) != null &&
1521                              (q = ch.find(h, k, kc)) != null))
1522                             return q;
1523                     }
1524                     dir = tieBreakOrder(k, pk);
1525                 }
1526 
1527                 TreeNode<K,V> xp = p;
1528                 if ((p = (dir <= 0) ? p.left : p.right) == null) {
1529                     Node<K,V> xpn = xp.next;
1530                     TreeNode<K,V> x = map.newTreeNode(h, k, v, xpn);
1531                     if (dir <= 0)
1532                         xp.left = x;
1533                     else
1534                         xp.right = x;
1535                     xp.next = x;
1536                     x.parent = x.prev = xp;
1537                     if (xpn != null)
1538                         ((TreeNode<K,V>)xpn).prev = x;
1539                     moveRootToFront(tab, balanceInsertion(root, x));
1540                     return null;
1541                 }
1542             }
1543         }
1544 
1545         final void removeTreeNode(HashMap<K,V> map, Node<K,V>[] tab,
1546                                   boolean movable) {
1547             int n;
1548             if (tab == null || (n = tab.length) == 0)
1549                 return;
1550             int index = (n - 1) & hash;
1551             TreeNode<K,V> first = (TreeNode<K,V>)tab[index], root = first, rl;
1552             TreeNode<K,V> succ = (TreeNode<K,V>)next, pred = prev;
1553             if (pred == null)
1554                 tab[index] = first = succ;
1555             else
1556                 pred.next = succ;
1557             if (succ != null)
1558                 succ.prev = pred;
1559             if (first == null)
1560                 return;
1561             if (root.parent != null)
1562                 root = root.root();
1563             if (root == null || root.right == null ||
1564                 (rl = root.left) == null || rl.left == null) {
1565                 tab[index] = first.untreeify(map);
1566                 return;
1567             }
1568             TreeNode<K,V> p = this, pl = left, pr = right, replacement;
1569             if (pl != null && pr != null) {
1570                 TreeNode<K,V> s = pr, sl;
1571                 while ((sl = s.left) != null)
1572                     s = sl;
1573                 boolean c = s.red; s.red = p.red; p.red = c;
1574                 TreeNode<K,V> sr = s.right;
1575                 TreeNode<K,V> pp = p.parent;
1576                 if (s == pr) {
1577                     p.parent = s;
1578                     s.right = p;
1579                 }
1580                 else {
1581                     TreeNode<K,V> sp = s.parent;
1582                     if ((p.parent = sp) != null) {
1583                         if (s == sp.left)
1584                             sp.left = p;
1585                         else
1586                             sp.right = p;
1587                     }
1588                     if ((s.right = pr) != null)
1589                         pr.parent = s;
1590                 }
1591                 p.left = null;
1592                 if ((p.right = sr) != null)
1593                     sr.parent = p;
1594                 if ((s.left = pl) != null)
1595                     pl.parent = s;
1596                 if ((s.parent = pp) == null)
1597                     root = s;
1598                 else if (p == pp.left)
1599                     pp.left = s;
1600                 else
1601                     pp.right = s;
1602                 if (sr != null)
1603                     replacement = sr;
1604                 else
1605                     replacement = p;
1606             }
1607             else if (pl != null)
1608                 replacement = pl;
1609             else if (pr != null)
1610                 replacement = pr;
1611             else
1612                 replacement = p;
1613             if (replacement != p) {
1614                 TreeNode<K,V> pp = replacement.parent = p.parent;
1615                 if (pp == null)
1616                     root = replacement;
1617                 else if (p == pp.left)
1618                     pp.left = replacement;
1619                 else
1620                     pp.right = replacement;
1621                 p.left = p.right = p.parent = null;
1622             }
1623 
1624             TreeNode<K,V> r = p.red ? root : balanceDeletion(root, replacement);
1625 
1626             if (replacement == p) {
1627                 TreeNode<K,V> pp = p.parent;
1628                 p.parent = null;
1629                 if (pp != null) {
1630                     if (p == pp.left)
1631                         pp.left = null;
1632                     else if (p == pp.right)
1633                         pp.right = null;
1634                 }
1635             }
1636             if (movable)
1637                 moveRootToFront(tab, r);
1638         }
1639 
1640         final void split(HashMap<K,V> map, Node<K,V>[] tab, int index, int bit) {
1641             TreeNode<K,V> b = this;
1642             TreeNode<K,V> loHead = null, loTail = null;
1643             TreeNode<K,V> hiHead = null, hiTail = null;
1644             int lc = 0, hc = 0;
1645             for (TreeNode<K,V> e = b, next; e != null; e = next) {
1646                 next = (TreeNode<K,V>)e.next;
1647                 e.next = null;
1648                 if ((e.hash & bit) == 0) {
1649                     if ((e.prev = loTail) == null)
1650                         loHead = e;
1651                     else
1652                         loTail.next = e;
1653                     loTail = e;
1654                     ++lc;
1655                 }
1656                 else {
1657                     if ((e.prev = hiTail) == null)
1658                         hiHead = e;
1659                     else
1660                         hiTail.next = e;
1661                     hiTail = e;
1662                     ++hc;
1663                 }
1664             }
1665 
1666             if (loHead != null) {
1667                 if (lc <= UNTREEIFY_THRESHOLD)
1668                     tab[index] = loHead.untreeify(map);
1669                 else {
1670                     tab[index] = loHead;
1671                     if (hiHead != null)
1672                         loHead.treeify(tab);
1673                 }
1674             }
1675             if (hiHead != null) {
1676                 if (hc <= UNTREEIFY_THRESHOLD)
1677                     tab[index + bit] = hiHead.untreeify(map);
1678                 else {
1679                     tab[index + bit] = hiHead;
1680                     if (loHead != null)
1681                         hiHead.treeify(tab);
1682                 }
1683             }
1684         }
1685 
1686         /* ---------------- Red-black tree methods, all adapted from CLR -------------- */
1687 
1688         static <K,V> TreeNode<K,V> rotateLeft(TreeNode<K,V> root,
1689                                               TreeNode<K,V> p) {
1690             TreeNode<K,V> r, pp, rl;
1691             if (p != null && (r = p.right) != null) {
1692                 if ((rl = p.right = r.left) != null)
1693                     rl.parent = p;
1694                 if ((pp = r.parent = p.parent) == null)
1695                     (root = r).red = false;
1696                 else if (pp.left == p)
1697                     pp.left = r;
1698                 else
1699                     pp.right = r;
1700                 r.left = p;
1701                 p.parent = r;
1702             }
1703             return root;
1704         }
1705 
1706         static <K,V> TreeNode<K,V> rotateRight(TreeNode<K,V> root,
1707                                                TreeNode<K,V> p) {
1708             TreeNode<K,V> l, pp, lr;
1709             if (p != null && (l = p.left) != null) {
1710                 if ((lr = p.left = l.right) != null)
1711                     lr.parent = p;
1712                 if ((pp = l.parent = p.parent) == null)
1713                     (root = l).red = false;
1714                 else if (pp.right == p)
1715                     pp.right = l;
1716                 else
1717                     pp.left = l;
1718                 l.right = p;
1719                 p.parent = l;
1720             }
1721             return root;
1722         }
1723 
1724         static <K,V> TreeNode<K,V> balanceInsertion(TreeNode<K,V> root,
1725                                                     TreeNode<K,V> x) {
1726             x.red = true;
1727             for (TreeNode<K,V> xp, xpp, xppl, xppr;;) {
1728                 if ((xp = x.parent) == null) {
1729                     x.red = false;
1730                     return x;
1731                 }
1732                 else if (!xp.red || (xpp = xp.parent) == null)
1733                     return root;
1734                 if (xp == (xppl = xpp.left)) {
1735                     if ((xppr = xpp.right) != null && xppr.red) {
1736                         xppr.red = false;
1737                         xp.red = false;
1738                         xpp.red = true;
1739                         x = xpp;
1740                     }
1741                     else {
1742                         if (x == xp.right) {
1743                             root = rotateLeft(root, x = xp);
1744                             xpp = (xp = x.parent) == null ? null : xp.parent;
1745                         }
1746                         if (xp != null) {
1747                             xp.red = false;
1748                             if (xpp != null) {
1749                                 xpp.red = true;
1750                                 root = rotateRight(root, xpp);
1751                             }
1752                         }
1753                     }
1754                 }
1755                 else {
1756                     if (xppl != null && xppl.red) {
1757                         xppl.red = false;
1758                         xp.red = false;
1759                         xpp.red = true;
1760                         x = xpp;
1761                     }
1762                     else {
1763                         if (x == xp.left) {
1764                             root = rotateRight(root, x = xp);
1765                             xpp = (xp = x.parent) == null ? null : xp.parent;
1766                         }
1767                         if (xp != null) {
1768                             xp.red = false;
1769                             if (xpp != null) {
1770                                 xpp.red = true;
1771                                 root = rotateLeft(root, xpp);
1772                             }
1773                         }
1774                     }
1775                 }
1776             }
1777         }
1778 
1779         static <K,V> TreeNode<K,V> balanceDeletion(TreeNode<K,V> root,
1780                                                    TreeNode<K,V> x) {
1781             for (TreeNode<K,V> xp, xpl, xpr;;)  {
1782                 if (x == null || x == root)
1783                     return root;
1784                 else if ((xp = x.parent) == null) {
1785                     x.red = false;
1786                     return x;
1787                 }
1788                 else if (x.red) {
1789                     x.red = false;
1790                     return root;
1791                 }
1792                 else if ((xpl = xp.left) == x) {
1793                     if ((xpr = xp.right) != null && xpr.red) {
1794                         xpr.red = false;
1795                         xp.red = true;
1796                         root = rotateLeft(root, xp);
1797                         xpr = (xp = x.parent) == null ? null : xp.right;
1798                     }
1799                     if (xpr == null)
1800                         x = xp;
1801                     else {
1802                         TreeNode<K,V> sl = xpr.left, sr = xpr.right;
1803                         if ((sr == null || !sr.red) &&
1804                             (sl == null || !sl.red)) {
1805                             xpr.red = true;
1806                             x = xp;
1807                         }
1808                         else {
1809                             if (sr == null || !sr.red) {
1810                                 if (sl != null)
1811                                     sl.red = false;
1812                                 xpr.red = true;
1813                                 root = rotateRight(root, xpr);
1814                                 xpr = (xp = x.parent) == null ?
1815                                     null : xp.right;
1816                             }
1817                             if (xpr != null) {
1818                                 xpr.red = (xp == null) ? false : xp.red;
1819                                 if ((sr = xpr.right) != null)
1820                                     sr.red = false;
1821                             }
1822                             if (xp != null) {
1823                                 xp.red = false;
1824                                 root = rotateLeft(root, xp);
1825                             }
1826                             x = root;
1827                         }
1828                     }
1829                 }
1830                 else {
1831                     if (xpl != null && xpl.red) {
1832                         xpl.red = false;
1833                         xp.red = true;
1834                         root = rotateRight(root, xp);
1835                         xpl = (xp = x.parent) == null ? null : xp.left;
1836                     }
1837                     if (xpl == null)
1838                         x = xp;
1839                     else {
1840                         TreeNode<K,V> sl = xpl.left, sr = xpl.right;
1841                         if ((sl == null || !sl.red) &&
1842                             (sr == null || !sr.red)) {
1843                             xpl.red = true;
1844                             x = xp;
1845                         }
1846                         else {
1847                             if (sl == null || !sl.red) {
1848                                 if (sr != null)
1849                                     sr.red = false;
1850                                 xpl.red = true;
1851                                 root = rotateLeft(root, xpl);
1852                                 xpl = (xp = x.parent) == null ?
1853                                     null : xp.left;
1854                             }
1855                             if (xpl != null) {
1856                                 xpl.red = (xp == null) ? false : xp.red;
1857                                 if ((sl = xpl.left) != null)
1858                                     sl.red = false;
1859                             }
1860                             if (xp != null) {
1861                                 xp.red = false;
1862                                 root = rotateRight(root, xp);
1863                             }
1864                             x = root;
1865                         }
1866                     }
1867                 }
1868             }
1869         }
1870 
1871         static <K,V> boolean checkInvariants(TreeNode<K,V> t) {
1872             TreeNode<K,V> tp = t.parent, tl = t.left, tr = t.right,
1873                 tb = t.prev, tn = (TreeNode<K,V>)t.next;
1874             if (tb != null && tb.next != t)
1875                 return false;
1876             if (tn != null && tn.prev != t)
1877                 return false;
1878             if (tp != null && t != tp.left && t != tp.right)
1879                 return false;
1880             if (tl != null && (tl.parent != t || tl.hash > t.hash))
1881                 return false;
1882             if (tr != null && (tr.parent != t || tr.hash < t.hash))
1883                 return false;
1884             if (t.red && tl != null && tl.red && tr != null && tr.red)
1885                 return false;
1886             if (tl != null && !checkInvariants(tl))
1887                 return false;
1888             if (tr != null && !checkInvariants(tr))
1889                 return false;
1890             return true;
1891         }
1892     }
1893 
1894 }

HashMap的put方法:

HashMap按value排序:

 

 1 import java.util.*;
 2 
 3 public class Demo {
 4     public static void main(String[] args) {
 5         Map<String, Integer> map = new HashMap<>();
 6         map.put("a", 1);
 7         map.put("c", 3);
 8         map.put("b", 5);
 9         map.put("f", 7);
10         map.put("e", 6);
11         map.put("d", 8);
12         List<Map.Entry<String, Integer>> list = new ArrayList<>(map.entrySet());
13         list.sort((m, n) -> n.getValue() - m.getValue());
14 
15         for (Map.Entry<String, Integer> entry : list) {
16             System.out.println(entry.getKey() + "=" + entry.getValue());
17         }
18     }
19 }
20 /**
21  * d=8
22  * f=7
23  * e=6
24  * b=5
25  * c=3
26  * a=1
27  */

 

posted @ 2018-03-16 11:21  sakura1027  阅读(341)  评论(0编辑  收藏  举报