源碼分析:java
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方法:node
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 */