1 /* 2 * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package java.util; 27 28 import java.io.*; 29 import java.lang.reflect.ParameterizedType; 30 import java.lang.reflect.Type; 31 import java.util.function.Consumer; 32 import java.util.function.BiFunction; 33 import java.util.function.Function; 34 35 /** 36 * Hash table based implementation of the <tt>Map</tt> interface. This 37 * implementation provides all of the optional map operations, and permits 38 * <tt>null</tt> values and the <tt>null</tt> key. (The <tt>HashMap</tt> 39 * class is roughly equivalent to <tt>Hashtable</tt>, except that it is 40 * unsynchronized and permits nulls.) This class makes no guarantees as to 41 * the order of the map; in particular, it does not guarantee that the order 42 * will remain constant over time. 43 * 44 * <p>This implementation provides constant-time performance for the basic 45 * operations (<tt>get</tt> and <tt>put</tt>), assuming the hash function 46 * disperses the elements properly among the buckets. Iteration over 47 * collection views requires time proportional to the "capacity" of the 48 * <tt>HashMap</tt> instance (the number of buckets) plus its size (the number 49 * of key-value mappings). Thus, it's very important not to set the initial 50 * capacity too high (or the load factor too low) if iteration performance is 51 * important. 52 * 53 * <p>An instance of <tt>HashMap</tt> has two parameters that affect its 54 * performance: <i>initial capacity</i> and <i>load factor</i>. The 55 * <i>capacity</i> is the number of buckets in the hash table, and the initial 56 * capacity is simply the capacity at the time the hash table is created. The 57 * <i>load factor</i> is a measure of how full the hash table is allowed to 58 * get before its capacity is automatically increased. When the number of 59 * entries in the hash table exceeds the product of the load factor and the 60 * current capacity, the hash table is <i>rehashed</i> (that is, internal data 61 * structures are rebuilt) so that the hash table has approximately twice the 62 * number of buckets. 63 * 64 * <p>As a general rule, the default load factor (.75) offers a good tradeoff 65 * between time and space costs. Higher values decrease the space overhead 66 * but increase the lookup cost (reflected in most of the operations of the 67 * <tt>HashMap</tt> class, including <tt>get</tt> and <tt>put</tt>). The 68 * expected number of entries in the map and its load factor should be taken 69 * into account when setting its initial capacity, so as to minimize the 70 * number of rehash operations. If the initial capacity is greater 71 * than the maximum number of entries divided by the load factor, no 72 * rehash operations will ever occur. 73 * 74 * <p>If many mappings are to be stored in a <tt>HashMap</tt> instance, 75 * creating it with a sufficiently large capacity will allow the mappings to 76 * be stored more efficiently than letting it perform automatic rehashing as 77 * needed to grow the table. 78 * 79 * <p><strong>Note that this implementation is not synchronized.</strong> 80 * If multiple threads access a hash map concurrently, and at least one of 81 * the threads modifies the map structurally, it <i>must</i> be 82 * synchronized externally. (A structural modification is any operation 83 * that adds or deletes one or more mappings; merely changing the value 84 * associated with a key that an instance already contains is not a 85 * structural modification.) This is typically accomplished by 86 * synchronizing on some object that naturally encapsulates the map. 87 * 88 * If no such object exists, the map should be "wrapped" using the 89 * {@link Collections#synchronizedMap Collections.synchronizedMap} 90 * method. This is best done at creation time, to prevent accidental 91 * unsynchronized access to the map:<pre> 92 * Map m = Collections.synchronizedMap(new HashMap(...));</pre> 93 * 94 * <p>The iterators returned by all of this class's "collection view methods" 95 * are <i>fail-fast</i>: if the map is structurally modified at any time after 96 * the iterator is created, in any way except through the iterator's own 97 * <tt>remove</tt> method, the iterator will throw a 98 * {@link ConcurrentModificationException}. Thus, in the face of concurrent 99 * modification, the iterator fails quickly and cleanly, rather than risking 100 * arbitrary, non-deterministic behavior at an undetermined time in the 101 * future. 102 * 103 * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed 104 * as it is, generally speaking, impossible to make any hard guarantees in the 105 * presence of unsynchronized concurrent modification. Fail-fast iterators 106 * throw <tt>ConcurrentModificationException</tt> on a best-effort basis. 107 * Therefore, it would be wrong to write a program that depended on this 108 * exception for its correctness: <i>the fail-fast behavior of iterators 109 * should be used only to detect bugs.</i> 110 * 111 * <p>This class is a member of the 112 * <a href="{@docRoot}/../technotes/guides/collections/index.html"> 113 * Java Collections Framework</a>. 114 * 115 * @param <K> the type of keys maintained by this map 116 * @param <V> the type of mapped values 117 * 118 * @author Doug Lea 119 * @author Josh Bloch 120 * @author Arthur van Hoff 121 * @author Neal Gafter 122 * @see Object#hashCode() 123 * @see Collection 124 * @see Map 125 * @see TreeMap 126 * @see Hashtable 127 * @since 1.2 128 */ 129 130 public class HashMap<K,V> 131 extends AbstractMap<K,V> 132 implements Map<K,V>, Cloneable, Serializable 133 { 134 135 /** 136 * The default initial capacity - MUST be a power of two. 137 */ 138 static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16 139 140 /** 141 * The maximum capacity, used if a higher value is implicitly specified 142 * by either of the constructors with arguments. 143 * MUST be a power of two <= 1<<30. 144 */ 145 static final int MAXIMUM_CAPACITY = 1 << 30; 146 147 /** 148 * The load factor used when none specified in constructor. 149 */ 150 static final float DEFAULT_LOAD_FACTOR = 0.75f; 151 152 /** 153 * An empty table instance to share when the table is not inflated. 154 */ 155 static final Object[] EMPTY_TABLE = {}; 156 157 /** 158 * The table, resized as necessary. Length MUST Always be a power of two. 159 */ 160 transient Object[] table = EMPTY_TABLE; 161 162 /** 163 * The number of key-value mappings contained in this map. 164 */ 165 transient int size; 166 167 /** 168 * The next size value at which to resize (capacity * load factor). 169 * @serial 170 */ 171 // If table == EMPTY_TABLE then this is the initial capacity at which the 172 // table will be created when inflated. 173 int threshold; 174 175 /** 176 * The load factor for the hash table. 177 * 178 * @serial 179 */ 180 final float loadFactor; 181 182 /** 183 * The number of times this HashMap has been structurally modified 184 * Structural modifications are those that change the number of mappings in 185 * the HashMap or otherwise modify its internal structure (e.g., 186 * rehash). This field is used to make iterators on Collection-views of 187 * the HashMap fail-fast. (See ConcurrentModificationException). 188 */ 189 transient int modCount; 190 191 /** 192 * Holds values which can't be initialized until after VM is booted. 193 */ 194 private static class Holder { 195 static final sun.misc.Unsafe UNSAFE; 196 197 /** 198 * Offset of "final" hashSeed field we must set in 199 * readObject() method. 200 */ 201 static final long HASHSEED_OFFSET; 202 203 static final boolean USE_HASHSEED; 204 205 static { 206 String hashSeedProp = java.security.AccessController.doPrivileged( 207 new sun.security.action.GetPropertyAction( 208 "jdk.map.useRandomSeed")); 209 boolean localBool = (null != hashSeedProp) 210 ? Boolean.parseBoolean(hashSeedProp) : false; 211 USE_HASHSEED = localBool; 212 213 if (USE_HASHSEED) { 214 try { 215 UNSAFE = sun.misc.Unsafe.getUnsafe(); 216 HASHSEED_OFFSET = UNSAFE.objectFieldOffset( 217 HashMap.class.getDeclaredField("hashSeed")); 218 } catch (NoSuchFieldException | SecurityException e) { 219 throw new InternalError("Failed to record hashSeed offset", e); 220 } 221 } else { 222 UNSAFE = null; 223 HASHSEED_OFFSET = 0; 224 } 225 } 226 } 227 228 /* 229 * A randomizing value associated with this instance that is applied to 230 * hash code of keys to make hash collisions harder to find. 231 * 232 * Non-final so it can be set lazily, but be sure not to set more than once. 233 */ 234 transient final int hashSeed; 235 236 /* 237 * TreeBin/TreeNode code from CHM doesn't handle the null key. Store the 238 * null key entry here. 239 */ 240 transient Entry<K,V> nullKeyEntry = null; 241 242 /* 243 * In order to improve performance under high hash-collision conditions, 244 * HashMap will switch to storing a bin's entries in a balanced tree 245 * (TreeBin) instead of a linked-list once the number of entries in the bin 246 * passes a certain threshold (TreeBin.TREE_THRESHOLD), if at least one of 247 * the keys in the bin implements Comparable. This technique is borrowed 248 * from ConcurrentHashMap. 249 */ 250 251 /* 252 * Code based on CHMv8 253 * 254 * Node type for TreeBin 255 */ 256 final static class TreeNode<K,V> { 257 TreeNode parent; // red-black tree links 258 TreeNode left; 259 TreeNode right; 260 TreeNode prev; // needed to unlink next upon deletion 261 boolean red; 262 final HashMap.Entry<K,V> entry; 263 264 TreeNode(HashMap.Entry<K,V> entry, Object next, TreeNode parent) { 265 this.entry = entry; 266 this.entry.next = next; 267 this.parent = parent; 268 } 269 } 270 271 /** 272 * Returns a Class for the given object of the form "class C 273 * implements Comparable<C>", if one exists, else null. See the TreeBin 274 * docs, below, for explanation. 275 */ 276 static Class<?> comparableClassFor(Object x) { 277 Class<?> c, s, cmpc; Type[] ts, as; Type t; ParameterizedType p; 278 if ((c = x.getClass()) == String.class) // bypass checks 279 return c; 280 if ((cmpc = Comparable.class).isAssignableFrom(c)) { 281 while (cmpc.isAssignableFrom(s = c.getSuperclass())) 282 c = s; // find topmost comparable class 283 if ((ts = c.getGenericInterfaces()) != null) { 284 for (int i = 0; i < ts.length; ++i) { 285 if (((t = ts[i]) instanceof ParameterizedType) && 286 ((p = (ParameterizedType)t).getRawType() == cmpc) && 287 (as = p.getActualTypeArguments()) != null && 288 as.length == 1 && as[0] == c) // type arg is c 289 return c; 290 } 291 } 292 } 293 return null; 294 } 295 296 /* 297 * Code based on CHMv8 298 * 299 * A specialized form of red-black tree for use in bins 300 * whose size exceeds a threshold. 301 * 302 * TreeBins use a special form of comparison for search and 303 * related operations (which is the main reason we cannot use 304 * existing collections such as TreeMaps). TreeBins contain 305 * Comparable elements, but may contain others, as well as 306 * elements that are Comparable but not necessarily Comparable<T> 307 * for the same T, so we cannot invoke compareTo among them. To 308 * handle this, the tree is ordered primarily by hash value, then 309 * by Comparable.compareTo order if applicable. On lookup at a 310 * node, if elements are not comparable or compare as 0 then both 311 * left and right children may need to be searched in the case of 312 * tied hash values. (This corresponds to the full list search 313 * that would be necessary if all elements were non-Comparable and 314 * had tied hashes.) The red-black balancing code is updated from 315 * pre-jdk-collections 316 * (http://gee.cs.oswego.edu/dl/classes/collections/RBCell.java) 317 * based in turn on Cormen, Leiserson, and Rivest "Introduction to 318 * Algorithms" (CLR). 319 */ 320 final class TreeBin { 321 /* 322 * The bin count threshold for using a tree rather than list for a bin. The 323 * value reflects the approximate break-even point for using tree-based 324 * operations. 325 */ 326 static final int TREE_THRESHOLD = 16; 327 328 TreeNode<K,V> root; // root of tree 329 TreeNode<K,V> first; // head of next-pointer list 330 331 /* 332 * Split a TreeBin into lo and hi parts and install in given table. 333 * 334 * Existing Entrys are re-used, which maintains the before/after links for 335 * LinkedHashMap.Entry. 336 * 337 * No check for Comparable, though this is the same as CHM. 338 */ 339 final void splitTreeBin(Object[] newTable, int i, TreeBin loTree, TreeBin hiTree) { 340 TreeBin oldTree = this; 341 int bit = newTable.length >>> 1; 342 int loCount = 0, hiCount = 0; 343 TreeNode<K,V> e = oldTree.first; 344 TreeNode<K,V> next; 345 346 // This method is called when the table has just increased capacity, 347 // so indexFor() is now taking one additional bit of hash into 348 // account ("bit"). Entries in this TreeBin now belong in one of 349 // two bins, "i" or "i+bit", depending on if the new top bit of the 350 // hash is set. The trees for the two bins are loTree and hiTree. 351 // If either tree ends up containing fewer than TREE_THRESHOLD 352 // entries, it is converted back to a linked list. 353 while (e != null) { 354 // Save entry.next - it will get overwritten in putTreeNode() 355 next = (TreeNode<K,V>)e.entry.next; 356 357 int h = e.entry.hash; 358 K k = (K) e.entry.key; 359 V v = e.entry.value; 360 if ((h & bit) == 0) { 361 ++loCount; 362 // Re-using e.entry 363 loTree.putTreeNode(h, k, v, e.entry); 364 } else { 365 ++hiCount; 366 hiTree.putTreeNode(h, k, v, e.entry); 367 } 368 // Iterate using the saved 'next' 369 e = next; 370 } 371 if (loCount < TREE_THRESHOLD) { // too small, convert back to list 372 HashMap.Entry loEntry = null; 373 TreeNode<K,V> p = loTree.first; 374 while (p != null) { 375 @SuppressWarnings("unchecked") 376 TreeNode<K,V> savedNext = (TreeNode<K,V>) p.entry.next; 377 p.entry.next = loEntry; 378 loEntry = p.entry; 379 p = savedNext; 380 } 381 // assert newTable[i] == null; 382 newTable[i] = loEntry; 383 } else { 384 // assert newTable[i] == null; 385 newTable[i] = loTree; 386 } 387 if (hiCount < TREE_THRESHOLD) { // too small, convert back to list 388 HashMap.Entry hiEntry = null; 389 TreeNode<K,V> p = hiTree.first; 390 while (p != null) { 391 @SuppressWarnings("unchecked") 392 TreeNode<K,V> savedNext = (TreeNode<K,V>) p.entry.next; 393 p.entry.next = hiEntry; 394 hiEntry = p.entry; 395 p = savedNext; 396 } 397 // assert newTable[i + bit] == null; 398 newTable[i + bit] = hiEntry; 399 } else { 400 // assert newTable[i + bit] == null; 401 newTable[i + bit] = hiTree; 402 } 403 } 404 405 /* 406 * Popuplate the TreeBin with entries from the linked list e 407 * 408 * Assumes 'this' is a new/empty TreeBin 409 * 410 * Note: no check for Comparable 411 * Note: I believe this changes iteration order 412 */ 413 @SuppressWarnings("unchecked") 414 void populate(HashMap.Entry e) { 415 // assert root == null; 416 // assert first == null; 417 HashMap.Entry next; 418 while (e != null) { 419 // Save entry.next - it will get overwritten in putTreeNode() 420 next = (HashMap.Entry)e.next; 421 // Re-using Entry e will maintain before/after in LinkedHM 422 putTreeNode(e.hash, (K)e.key, (V)e.value, e); 423 // Iterate using the saved 'next' 424 e = next; 425 } 426 } 427 428 /** 429 * Copied from CHMv8 430 * From CLR 431 */ 432 private void rotateLeft(TreeNode p) { 433 if (p != null) { 434 TreeNode r = p.right, pp, rl; 435 if ((rl = p.right = r.left) != null) { 436 rl.parent = p; 437 } 438 if ((pp = r.parent = p.parent) == null) { 439 root = r; 440 } else if (pp.left == p) { 441 pp.left = r; 442 } else { 443 pp.right = r; 444 } 445 r.left = p; 446 p.parent = r; 447 } 448 } 449 450 /** 451 * Copied from CHMv8 452 * From CLR 453 */ 454 private void rotateRight(TreeNode p) { 455 if (p != null) { 456 TreeNode l = p.left, pp, lr; 457 if ((lr = p.left = l.right) != null) { 458 lr.parent = p; 459 } 460 if ((pp = l.parent = p.parent) == null) { 461 root = l; 462 } else if (pp.right == p) { 463 pp.right = l; 464 } else { 465 pp.left = l; 466 } 467 l.right = p; 468 p.parent = l; 469 } 470 } 471 472 /** 473 * Returns the TreeNode (or null if not found) for the given 474 * key. A front-end for recursive version. 475 */ 476 final TreeNode getTreeNode(int h, K k) { 477 return getTreeNode(h, k, root, comparableClassFor(k)); 478 } 479 480 /** 481 * Returns the TreeNode (or null if not found) for the given key 482 * starting at given root. 483 */ 484 @SuppressWarnings("unchecked") 485 final TreeNode getTreeNode (int h, K k, TreeNode p, Class<?> cc) { 486 // assert k != null; 487 while (p != null) { 488 int dir, ph; Object pk; 489 if ((ph = p.entry.hash) != h) 490 dir = (h < ph) ? -1 : 1; 491 else if ((pk = p.entry.key) == k || k.equals(pk)) 492 return p; 493 else if (cc == null || comparableClassFor(pk) != cc || 494 (dir = ((Comparable<Object>)k).compareTo(pk)) == 0) { 495 // assert pk != null; 496 TreeNode r, pl, pr; // check both sides 497 if ((pr = p.right) != null && 498 (r = getTreeNode(h, k, pr, cc)) != null) 499 return r; 500 else if ((pl = p.left) != null) 501 dir = -1; 502 else // nothing there 503 break; 504 } 505 p = (dir > 0) ? p.right : p.left; 506 } 507 return null; 508 } 509 510 /* 511 * Finds or adds a node. 512 * 513 * 'entry' should be used to recycle an existing Entry (e.g. in the case 514 * of converting a linked-list bin to a TreeBin). 515 * If entry is null, a new Entry will be created for the new TreeNode 516 * 517 * @return the TreeNode containing the mapping, or null if a new 518 * TreeNode was added 519 */ 520 @SuppressWarnings("unchecked") 521 TreeNode putTreeNode(int h, K k, V v, HashMap.Entry<K,V> entry) { 522 // assert k != null; 523 //if (entry != null) { 524 // assert h == entry.hash; 525 // assert k == entry.key; 526 // assert v == entry.value; 527 // } 528 Class<?> cc = comparableClassFor(k); 529 TreeNode pp = root, p = null; 530 int dir = 0; 531 while (pp != null) { // find existing node or leaf to insert at 532 int ph; Object pk; 533 p = pp; 534 if ((ph = p.entry.hash) != h) 535 dir = (h < ph) ? -1 : 1; 536 else if ((pk = p.entry.key) == k || k.equals(pk)) 537 return p; 538 else if (cc == null || comparableClassFor(pk) != cc || 539 (dir = ((Comparable<Object>)k).compareTo(pk)) == 0) { 540 TreeNode r, pr; 541 if ((pr = p.right) != null && 542 (r = getTreeNode(h, k, pr, cc)) != null) 543 return r; 544 else // continue left 545 dir = -1; 546 } 547 pp = (dir > 0) ? p.right : p.left; 548 } 549 550 // Didn't find the mapping in the tree, so add it 551 TreeNode f = first; 552 TreeNode x; 553 if (entry != null) { 554 x = new TreeNode(entry, f, p); 555 } else { 556 x = new TreeNode(newEntry(h, k, v, null), f, p); 557 } 558 first = x; 559 560 if (p == null) { 561 root = x; 562 } else { // attach and rebalance; adapted from CLR 563 TreeNode xp, xpp; 564 if (f != null) { 565 f.prev = x; 566 } 567 if (dir <= 0) { 568 p.left = x; 569 } else { 570 p.right = x; 571 } 572 x.red = true; 573 while (x != null && (xp = x.parent) != null && xp.red 574 && (xpp = xp.parent) != null) { 575 TreeNode xppl = xpp.left; 576 if (xp == xppl) { 577 TreeNode y = xpp.right; 578 if (y != null && y.red) { 579 y.red = false; 580 xp.red = false; 581 xpp.red = true; 582 x = xpp; 583 } else { 584 if (x == xp.right) { 585 rotateLeft(x = xp); 586 xpp = (xp = x.parent) == null ? null : xp.parent; 587 } 588 if (xp != null) { 589 xp.red = false; 590 if (xpp != null) { 591 xpp.red = true; 592 rotateRight(xpp); 593 } 594 } 595 } 596 } else { 597 TreeNode y = xppl; 598 if (y != null && y.red) { 599 y.red = false; 600 xp.red = false; 601 xpp.red = true; 602 x = xpp; 603 } else { 604 if (x == xp.left) { 605 rotateRight(x = xp); 606 xpp = (xp = x.parent) == null ? null : xp.parent; 607 } 608 if (xp != null) { 609 xp.red = false; 610 if (xpp != null) { 611 xpp.red = true; 612 rotateLeft(xpp); 613 } 614 } 615 } 616 } 617 } 618 TreeNode r = root; 619 if (r != null && r.red) { 620 r.red = false; 621 } 622 } 623 return null; 624 } 625 626 /* 627 * From CHMv8 628 * 629 * Removes the given node, that must be present before this 630 * call. This is messier than typical red-black deletion code 631 * because we cannot swap the contents of an interior node 632 * with a leaf successor that is pinned by "next" pointers 633 * that are accessible independently of lock. So instead we 634 * swap the tree linkages. 635 */ 636 final void deleteTreeNode(TreeNode p) { 637 TreeNode next = (TreeNode) p.entry.next; // unlink traversal pointers 638 TreeNode pred = p.prev; 639 if (pred == null) { 640 first = next; 641 } else { 642 pred.entry.next = next; 643 } 644 if (next != null) { 645 next.prev = pred; 646 } 647 TreeNode replacement; 648 TreeNode pl = p.left; 649 TreeNode pr = p.right; 650 if (pl != null && pr != null) { 651 TreeNode s = pr, sl; 652 while ((sl = s.left) != null) // find successor 653 { 654 s = sl; 655 } 656 boolean c = s.red; 657 s.red = p.red; 658 p.red = c; // swap colors 659 TreeNode sr = s.right; 660 TreeNode pp = p.parent; 661 if (s == pr) { // p was s's direct parent 662 p.parent = s; 663 s.right = p; 664 } else { 665 TreeNode sp = s.parent; 666 if ((p.parent = sp) != null) { 667 if (s == sp.left) { 668 sp.left = p; 669 } else { 670 sp.right = p; 671 } 672 } 673 if ((s.right = pr) != null) { 674 pr.parent = s; 675 } 676 } 677 p.left = null; 678 if ((p.right = sr) != null) { 679 sr.parent = p; 680 } 681 if ((s.left = pl) != null) { 682 pl.parent = s; 683 } 684 if ((s.parent = pp) == null) { 685 root = s; 686 } else if (p == pp.left) { 687 pp.left = s; 688 } else { 689 pp.right = s; 690 } 691 replacement = sr; 692 } else { 693 replacement = (pl != null) ? pl : pr; 694 } 695 TreeNode pp = p.parent; 696 if (replacement == null) { 697 if (pp == null) { 698 root = null; 699 return; 700 } 701 replacement = p; 702 } else { 703 replacement.parent = pp; 704 if (pp == null) { 705 root = replacement; 706 } else if (p == pp.left) { 707 pp.left = replacement; 708 } else { 709 pp.right = replacement; 710 } 711 p.left = p.right = p.parent = null; 712 } 713 if (!p.red) { // rebalance, from CLR 714 TreeNode x = replacement; 715 while (x != null) { 716 TreeNode xp, xpl; 717 if (x.red || (xp = x.parent) == null) { 718 x.red = false; 719 break; 720 } 721 if (x == (xpl = xp.left)) { 722 TreeNode sib = xp.right; 723 if (sib != null && sib.red) { 724 sib.red = false; 725 xp.red = true; 726 rotateLeft(xp); 727 sib = (xp = x.parent) == null ? null : xp.right; 728 } 729 if (sib == null) { 730 x = xp; 731 } else { 732 TreeNode sl = sib.left, sr = sib.right; 733 if ((sr == null || !sr.red) 734 && (sl == null || !sl.red)) { 735 sib.red = true; 736 x = xp; 737 } else { 738 if (sr == null || !sr.red) { 739 if (sl != null) { 740 sl.red = false; 741 } 742 sib.red = true; 743 rotateRight(sib); 744 sib = (xp = x.parent) == null ? 745 null : xp.right; 746 } 747 if (sib != null) { 748 sib.red = (xp == null) ? false : xp.red; 749 if ((sr = sib.right) != null) { 750 sr.red = false; 751 } 752 } 753 if (xp != null) { 754 xp.red = false; 755 rotateLeft(xp); 756 } 757 x = root; 758 } 759 } 760 } else { // symmetric 761 TreeNode sib = xpl; 762 if (sib != null && sib.red) { 763 sib.red = false; 764 xp.red = true; 765 rotateRight(xp); 766 sib = (xp = x.parent) == null ? null : xp.left; 767 } 768 if (sib == null) { 769 x = xp; 770 } else { 771 TreeNode sl = sib.left, sr = sib.right; 772 if ((sl == null || !sl.red) 773 && (sr == null || !sr.red)) { 774 sib.red = true; 775 x = xp; 776 } else { 777 if (sl == null || !sl.red) { 778 if (sr != null) { 779 sr.red = false; 780 } 781 sib.red = true; 782 rotateLeft(sib); 783 sib = (xp = x.parent) == null ? 784 null : xp.left; 785 } 786 if (sib != null) { 787 sib.red = (xp == null) ? false : xp.red; 788 if ((sl = sib.left) != null) { 789 sl.red = false; 790 } 791 } 792 if (xp != null) { 793 xp.red = false; 794 rotateRight(xp); 795 } 796 x = root; 797 } 798 } 799 } 800 } 801 } 802 if (p == replacement && (pp = p.parent) != null) { 803 if (p == pp.left) // detach pointers 804 { 805 pp.left = null; 806 } else if (p == pp.right) { 807 pp.right = null; 808 } 809 p.parent = null; 810 } 811 } 812 } 813 814 /** 815 * Constructs an empty <tt>HashMap</tt> with the specified initial 816 * capacity and load factor. 817 * 818 * @param initialCapacity the initial capacity 819 * @param loadFactor the load factor 820 * @throws IllegalArgumentException if the initial capacity is negative 821 * or the load factor is nonpositive 822 */ 823 public HashMap(int initialCapacity, float loadFactor) { 824 if (initialCapacity < 0) 825 throw new IllegalArgumentException("Illegal initial capacity: " + 826 initialCapacity); 827 if (initialCapacity > MAXIMUM_CAPACITY) 828 initialCapacity = MAXIMUM_CAPACITY; 829 if (loadFactor <= 0 || Float.isNaN(loadFactor)) 830 throw new IllegalArgumentException("Illegal load factor: " + 831 loadFactor); 832 this.loadFactor = loadFactor; 833 threshold = initialCapacity; 834 hashSeed = initHashSeed(); 835 init(); 836 } 837 838 /** 839 * Constructs an empty <tt>HashMap</tt> with the specified initial 840 * capacity and the default load factor (0.75). 841 * 842 * @param initialCapacity the initial capacity. 843 * @throws IllegalArgumentException if the initial capacity is negative. 844 */ 845 public HashMap(int initialCapacity) { 846 this(initialCapacity, DEFAULT_LOAD_FACTOR); 847 } 848 849 /** 850 * Constructs an empty <tt>HashMap</tt> with the default initial capacity 851 * (16) and the default load factor (0.75). 852 */ 853 public HashMap() { 854 this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR); 855 } 856 857 /** 858 * Constructs a new <tt>HashMap</tt> with the same mappings as the 859 * specified <tt>Map</tt>. The <tt>HashMap</tt> is created with 860 * default load factor (0.75) and an initial capacity sufficient to 861 * hold the mappings in the specified <tt>Map</tt>. 862 * 863 * @param m the map whose mappings are to be placed in this map 864 * @throws NullPointerException if the specified map is null 865 */ 866 public HashMap(Map<? extends K, ? extends V> m) { 867 this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1, 868 DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR); 869 inflateTable(threshold); 870 871 putAllForCreate(m); 872 // assert size == m.size(); 873 } 874 875 private static int roundUpToPowerOf2(int number) { 876 // assert number >= 0 : "number must be non-negative"; 877 int rounded = number >= MAXIMUM_CAPACITY 878 ? MAXIMUM_CAPACITY 879 : (rounded = Integer.highestOneBit(number)) != 0 880 ? (Integer.bitCount(number) > 1) ? rounded << 1 : rounded 881 : 1; 882 883 return rounded; 884 } 885 886 /** 887 * Inflates the table. 888 */ 889 private void inflateTable(int toSize) { 890 // Find a power of 2 >= toSize 891 int capacity = roundUpToPowerOf2(toSize); 892 893 threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1); 894 table = new Object[capacity]; 895 } 896 897 // internal utilities 898 899 /** 900 * Initialization hook for subclasses. This method is called 901 * in all constructors and pseudo-constructors (clone, readObject) 902 * after HashMap has been initialized but before any entries have 903 * been inserted. (In the absence of this method, readObject would 904 * require explicit knowledge of subclasses.) 905 */ 906 void init() { 907 } 908 909 /** 910 * Return an initial value for the hashSeed, or 0 if the random seed is not 911 * enabled. 912 */ 913 final int initHashSeed() { 914 if (sun.misc.VM.isBooted() && Holder.USE_HASHSEED) { 915 return sun.misc.Hashing.randomHashSeed(this); 916 } 917 return 0; 918 } 919 920 /** 921 * Retrieve object hash code and applies a supplemental hash function to the 922 * result hash, which defends against poor quality hash functions. This is 923 * critical because HashMap uses power-of-two length hash tables, that 924 * otherwise encounter collisions for hashCodes that do not differ 925 * in lower bits. 926 */ 927 final int hash(Object k) { 928 int h = hashSeed ^ k.hashCode(); 929 930 // This function ensures that hashCodes that differ only by 931 // constant multiples at each bit position have a bounded 932 // number of collisions (approximately 8 at default load factor). 933 h ^= (h >>> 20) ^ (h >>> 12); 934 return h ^ (h >>> 7) ^ (h >>> 4); 935 } 936 937 /** 938 * Returns index for hash code h. 939 */ 940 static int indexFor(int h, int length) { 941 // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2"; 942 return h & (length-1); 943 } 944 945 /** 946 * Returns the number of key-value mappings in this map. 947 * 948 * @return the number of key-value mappings in this map 949 */ 950 public int size() { 951 return size; 952 } 953 954 /** 955 * Returns <tt>true</tt> if this map contains no key-value mappings. 956 * 957 * @return <tt>true</tt> if this map contains no key-value mappings 958 */ 959 public boolean isEmpty() { 960 return size == 0; 961 } 962 963 /** 964 * Returns the value to which the specified key is mapped, 965 * or {@code null} if this map contains no mapping for the key. 966 * 967 * <p>More formally, if this map contains a mapping from a key 968 * {@code k} to a value {@code v} such that {@code (key==null ? k==null : 969 * key.equals(k))}, then this method returns {@code v}; otherwise 970 * it returns {@code null}. (There can be at most one such mapping.) 971 * 972 * <p>A return value of {@code null} does not <i>necessarily</i> 973 * indicate that the map contains no mapping for the key; it's also 974 * possible that the map explicitly maps the key to {@code null}. 975 * The {@link #containsKey containsKey} operation may be used to 976 * distinguish these two cases. 977 * 978 * @see #put(Object, Object) 979 */ 980 @SuppressWarnings("unchecked") 981 public V get(Object key) { 982 Entry<K,V> entry = getEntry(key); 983 984 return null == entry ? null : entry.getValue(); 985 } 986 987 @Override 988 public V getOrDefault(Object key, V defaultValue) { 989 Entry<K,V> entry = getEntry(key); 990 991 return (entry == null) ? defaultValue : entry.getValue(); 992 } 993 994 /** 995 * Returns <tt>true</tt> if this map contains a mapping for the 996 * specified key. 997 * 998 * @param key The key whose presence in this map is to be tested 999 * @return <tt>true</tt> if this map contains a mapping for the specified 1000 * key. 1001 */ 1002 public boolean containsKey(Object key) { 1003 return getEntry(key) != null; 1004 } 1005 1006 /** 1007 * Returns the entry associated with the specified key in the 1008 * HashMap. Returns null if the HashMap contains no mapping 1009 * for the key. 1010 */ 1011 @SuppressWarnings("unchecked") 1012 final Entry<K,V> getEntry(Object key) { 1013 if (isEmpty()) { 1014 return null; 1015 } 1016 if (key == null) { 1017 return nullKeyEntry; 1018 } 1019 int hash = hash(key); 1020 int bin = indexFor(hash, table.length); 1021 1022 if (table[bin] instanceof Entry) { 1023 Entry<K,V> e = (Entry<K,V>) table[bin]; 1024 for (; e != null; e = (Entry<K,V>)e.next) { 1025 Object k; 1026 if (e.hash == hash && 1027 ((k = e.key) == key || key.equals(k))) { 1028 return e; 1029 } 1030 } 1031 } else if (table[bin] != null) { 1032 TreeBin e = (TreeBin)table[bin]; 1033 TreeNode p = e.getTreeNode(hash, (K)key); 1034 if (p != null) { 1035 // assert p.entry.hash == hash && p.entry.key.equals(key); 1036 return (Entry<K,V>)p.entry; 1037 } else { 1038 return null; 1039 } 1040 } 1041 return null; 1042 } 1043 1044 1045 /** 1046 * Associates the specified value with the specified key in this map. 1047 * If the map previously contained a mapping for the key, the old 1048 * value is replaced. 1049 * 1050 * @param key key with which the specified value is to be associated 1051 * @param value value to be associated with the specified key 1052 * @return the previous value associated with <tt>key</tt>, or 1053 * <tt>null</tt> if there was no mapping for <tt>key</tt>. 1054 * (A <tt>null</tt> return can also indicate that the map 1055 * previously associated <tt>null</tt> with <tt>key</tt>.) 1056 */ 1057 @SuppressWarnings("unchecked") 1058 public V put(K key, V value) { 1059 if (table == EMPTY_TABLE) { 1060 inflateTable(threshold); 1061 } 1062 if (key == null) 1063 return putForNullKey(value); 1064 int hash = hash(key); 1065 int i = indexFor(hash, table.length); 1066 boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? 1067 1068 if (table[i] instanceof Entry) { 1069 // Bin contains ordinary Entries. Search for key in the linked list 1070 // of entries, counting the number of entries. Only check for 1071 // TreeBin conversion if the list size is >= TREE_THRESHOLD. 1072 // (The conversion still may not happen if the table gets resized.) 1073 int listSize = 0; 1074 Entry<K,V> e = (Entry<K,V>) table[i]; 1075 for (; e != null; e = (Entry<K,V>)e.next) { 1076 Object k; 1077 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 1078 V oldValue = e.value; 1079 e.value = value; 1080 e.recordAccess(this); 1081 return oldValue; 1082 } 1083 listSize++; 1084 } 1085 // Didn't find, so fall through and call addEntry() to add the 1086 // Entry and check for TreeBin conversion. 1087 checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; 1088 } else if (table[i] != null) { 1089 TreeBin e = (TreeBin)table[i]; 1090 TreeNode p = e.putTreeNode(hash, key, value, null); 1091 if (p == null) { // putTreeNode() added a new node 1092 modCount++; 1093 size++; 1094 if (size >= threshold) { 1095 resize(2 * table.length); 1096 } 1097 return null; 1098 } else { // putTreeNode() found an existing node 1099 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1100 V oldVal = pEntry.value; 1101 pEntry.value = value; 1102 pEntry.recordAccess(this); 1103 return oldVal; 1104 } 1105 } 1106 modCount++; 1107 addEntry(hash, key, value, i, checkIfNeedTree); 1108 return null; 1109 } 1110 1111 /** 1112 * Offloaded version of put for null keys 1113 */ 1114 private V putForNullKey(V value) { 1115 if (nullKeyEntry != null) { 1116 V oldValue = nullKeyEntry.value; 1117 nullKeyEntry.value = value; 1118 nullKeyEntry.recordAccess(this); 1119 return oldValue; 1120 } 1121 modCount++; 1122 size++; // newEntry() skips size++ 1123 nullKeyEntry = newEntry(0, null, value, null); 1124 return null; 1125 } 1126 1127 private void putForCreateNullKey(V value) { 1128 // Look for preexisting entry for key. This will never happen for 1129 // clone or deserialize. It will only happen for construction if the 1130 // input Map is a sorted map whose ordering is inconsistent w/ equals. 1131 if (nullKeyEntry != null) { 1132 nullKeyEntry.value = value; 1133 } else { 1134 nullKeyEntry = newEntry(0, null, value, null); 1135 size++; 1136 } 1137 } 1138 1139 1140 /** 1141 * This method is used instead of put by constructors and 1142 * pseudoconstructors (clone, readObject). It does not resize the table, 1143 * check for comodification, etc, though it will convert bins to TreeBins 1144 * as needed. It calls createEntry rather than addEntry. 1145 */ 1146 @SuppressWarnings("unchecked") 1147 private void putForCreate(K key, V value) { 1148 if (null == key) { 1149 putForCreateNullKey(value); 1150 return; 1151 } 1152 int hash = hash(key); 1153 int i = indexFor(hash, table.length); 1154 boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? 1155 1156 /** 1157 * Look for preexisting entry for key. This will never happen for 1158 * clone or deserialize. It will only happen for construction if the 1159 * input Map is a sorted map whose ordering is inconsistent w/ equals. 1160 */ 1161 if (table[i] instanceof Entry) { 1162 int listSize = 0; 1163 Entry<K,V> e = (Entry<K,V>) table[i]; 1164 for (; e != null; e = (Entry<K,V>)e.next) { 1165 Object k; 1166 if (e.hash == hash && ((k = e.key) == key || key.equals(k))) { 1167 e.value = value; 1168 return; 1169 } 1170 listSize++; 1171 } 1172 // Didn't find, fall through to createEntry(). 1173 // Check for conversion to TreeBin done via createEntry(). 1174 checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; 1175 } else if (table[i] != null) { 1176 TreeBin e = (TreeBin)table[i]; 1177 TreeNode p = e.putTreeNode(hash, key, value, null); 1178 if (p != null) { 1179 p.entry.setValue(value); // Found an existing node, set value 1180 } else { 1181 size++; // Added a new TreeNode, so update size 1182 } 1183 // don't need modCount++/check for resize - just return 1184 return; 1185 } 1186 1187 createEntry(hash, key, value, i, checkIfNeedTree); 1188 } 1189 1190 private void putAllForCreate(Map<? extends K, ? extends V> m) { 1191 for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) 1192 putForCreate(e.getKey(), e.getValue()); 1193 } 1194 1195 /** 1196 * Rehashes the contents of this map into a new array with a 1197 * larger capacity. This method is called automatically when the 1198 * number of keys in this map reaches its threshold. 1199 * 1200 * If current capacity is MAXIMUM_CAPACITY, this method does not 1201 * resize the map, but sets threshold to Integer.MAX_VALUE. 1202 * This has the effect of preventing future calls. 1203 * 1204 * @param newCapacity the new capacity, MUST be a power of two; 1205 * must be greater than current capacity unless current 1206 * capacity is MAXIMUM_CAPACITY (in which case value 1207 * is irrelevant). 1208 */ 1209 void resize(int newCapacity) { 1210 Object[] oldTable = table; 1211 int oldCapacity = oldTable.length; 1212 if (oldCapacity == MAXIMUM_CAPACITY) { 1213 threshold = Integer.MAX_VALUE; 1214 return; 1215 } 1216 1217 Object[] newTable = new Object[newCapacity]; 1218 transfer(newTable); 1219 table = newTable; 1220 threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1); 1221 } 1222 1223 /** 1224 * Transfers all entries from current table to newTable. 1225 * 1226 * Assumes newTable is larger than table 1227 */ 1228 @SuppressWarnings("unchecked") 1229 void transfer(Object[] newTable) { 1230 Object[] src = table; 1231 // assert newTable.length > src.length : "newTable.length(" + 1232 // newTable.length + ") expected to be > src.length("+src.length+")"; 1233 int newCapacity = newTable.length; 1234 for (int j = 0; j < src.length; j++) { 1235 if (src[j] instanceof Entry) { 1236 // Assume: since wasn't TreeBin before, won't need TreeBin now 1237 Entry<K,V> e = (Entry<K,V>) src[j]; 1238 while (null != e) { 1239 Entry<K,V> next = (Entry<K,V>)e.next; 1240 int i = indexFor(e.hash, newCapacity); 1241 e.next = (Entry<K,V>) newTable[i]; 1242 newTable[i] = e; 1243 e = next; 1244 } 1245 } else if (src[j] != null) { 1246 TreeBin e = (TreeBin) src[j]; 1247 TreeBin loTree = new TreeBin(); 1248 TreeBin hiTree = new TreeBin(); 1249 e.splitTreeBin(newTable, j, loTree, hiTree); 1250 } 1251 } 1252 Arrays.fill(table, null); 1253 } 1254 1255 /** 1256 * Copies all of the mappings from the specified map to this map. 1257 * These mappings will replace any mappings that this map had for 1258 * any of the keys currently in the specified map. 1259 * 1260 * @param m mappings to be stored in this map 1261 * @throws NullPointerException if the specified map is null 1262 */ 1263 public void putAll(Map<? extends K, ? extends V> m) { 1264 int numKeysToBeAdded = m.size(); 1265 if (numKeysToBeAdded == 0) 1266 return; 1267 1268 if (table == EMPTY_TABLE) { 1269 inflateTable((int) Math.max(numKeysToBeAdded * loadFactor, threshold)); 1270 } 1271 1272 /* 1273 * Expand the map if the map if the number of mappings to be added 1274 * is greater than or equal to threshold. This is conservative; the 1275 * obvious condition is (m.size() + size) >= threshold, but this 1276 * condition could result in a map with twice the appropriate capacity, 1277 * if the keys to be added overlap with the keys already in this map. 1278 * By using the conservative calculation, we subject ourself 1279 * to at most one extra resize. 1280 */ 1281 if (numKeysToBeAdded > threshold && table.length < MAXIMUM_CAPACITY) { 1282 resize(table.length * 2); 1283 } 1284 1285 for (Map.Entry<? extends K, ? extends V> e : m.entrySet()) 1286 put(e.getKey(), e.getValue()); 1287 } 1288 1289 /** 1290 * Removes the mapping for the specified key from this map if present. 1291 * 1292 * @param key key whose mapping is to be removed from the map 1293 * @return the previous value associated with <tt>key</tt>, or 1294 * <tt>null</tt> if there was no mapping for <tt>key</tt>. 1295 * (A <tt>null</tt> return can also indicate that the map 1296 * previously associated <tt>null</tt> with <tt>key</tt>.) 1297 */ 1298 public V remove(Object key) { 1299 Entry<K,V> e = removeEntryForKey(key); 1300 return (e == null ? null : e.value); 1301 } 1302 1303 // optimized implementations of default methods in Map 1304 1305 @Override 1306 public V putIfAbsent(K key, V value) { 1307 if (table == EMPTY_TABLE) { 1308 inflateTable(threshold); 1309 } 1310 if (key == null) { 1311 if (nullKeyEntry == null || nullKeyEntry.value == null) { 1312 putForNullKey(value); 1313 return null; 1314 } else { 1315 return nullKeyEntry.value; 1316 } 1317 } 1318 int hash = hash(key); 1319 int i = indexFor(hash, table.length); 1320 boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? 1321 1322 if (table[i] instanceof Entry) { 1323 int listSize = 0; 1324 Entry<K,V> e = (Entry<K,V>) table[i]; 1325 for (; e != null; e = (Entry<K,V>)e.next) { 1326 if (e.hash == hash && Objects.equals(e.key, key)) { 1327 if (e.value != null) { 1328 return e.value; 1329 } 1330 e.value = value; 1331 e.recordAccess(this); 1332 return null; 1333 } 1334 listSize++; 1335 } 1336 // Didn't find, so fall through and call addEntry() to add the 1337 // Entry and check for TreeBin conversion. 1338 checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; 1339 } else if (table[i] != null) { 1340 TreeBin e = (TreeBin)table[i]; 1341 TreeNode p = e.putTreeNode(hash, key, value, null); 1342 if (p == null) { // not found, putTreeNode() added a new node 1343 modCount++; 1344 size++; 1345 if (size >= threshold) { 1346 resize(2 * table.length); 1347 } 1348 return null; 1349 } else { // putTreeNode() found an existing node 1350 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1351 V oldVal = pEntry.value; 1352 if (oldVal == null) { // only replace if maps to null 1353 pEntry.value = value; 1354 pEntry.recordAccess(this); 1355 } 1356 return oldVal; 1357 } 1358 } 1359 modCount++; 1360 addEntry(hash, key, value, i, checkIfNeedTree); 1361 return null; 1362 } 1363 1364 @Override 1365 public boolean remove(Object key, Object value) { 1366 if (isEmpty()) { 1367 return false; 1368 } 1369 if (key == null) { 1370 if (nullKeyEntry != null && 1371 Objects.equals(nullKeyEntry.value, value)) { 1372 removeNullKey(); 1373 return true; 1374 } 1375 return false; 1376 } 1377 int hash = hash(key); 1378 int i = indexFor(hash, table.length); 1379 1380 if (table[i] instanceof Entry) { 1381 @SuppressWarnings("unchecked") 1382 Entry<K,V> prev = (Entry<K,V>) table[i]; 1383 Entry<K,V> e = prev; 1384 while (e != null) { 1385 @SuppressWarnings("unchecked") 1386 Entry<K,V> next = (Entry<K,V>) e.next; 1387 if (e.hash == hash && Objects.equals(e.key, key)) { 1388 if (!Objects.equals(e.value, value)) { 1389 return false; 1390 } 1391 modCount++; 1392 size--; 1393 if (prev == e) 1394 table[i] = next; 1395 else 1396 prev.next = next; 1397 e.recordRemoval(this); 1398 return true; 1399 } 1400 prev = e; 1401 e = next; 1402 } 1403 } else if (table[i] != null) { 1404 TreeBin tb = ((TreeBin) table[i]); 1405 TreeNode p = tb.getTreeNode(hash, (K)key); 1406 if (p != null) { 1407 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1408 // assert pEntry.key.equals(key); 1409 if (Objects.equals(pEntry.value, value)) { 1410 modCount++; 1411 size--; 1412 tb.deleteTreeNode(p); 1413 pEntry.recordRemoval(this); 1414 if (tb.root == null || tb.first == null) { 1415 // assert tb.root == null && tb.first == null : 1416 // "TreeBin.first and root should both be null"; 1417 // TreeBin is now empty, we should blank this bin 1418 table[i] = null; 1419 } 1420 return true; 1421 } 1422 } 1423 } 1424 return false; 1425 } 1426 1427 @Override 1428 public boolean replace(K key, V oldValue, V newValue) { 1429 if (isEmpty()) { 1430 return false; 1431 } 1432 if (key == null) { 1433 if (nullKeyEntry != null && 1434 Objects.equals(nullKeyEntry.value, oldValue)) { 1435 putForNullKey(newValue); 1436 return true; 1437 } 1438 return false; 1439 } 1440 int hash = hash(key); 1441 int i = indexFor(hash, table.length); 1442 1443 if (table[i] instanceof Entry) { 1444 @SuppressWarnings("unchecked") 1445 Entry<K,V> e = (Entry<K,V>) table[i]; 1446 for (; e != null; e = (Entry<K,V>)e.next) { 1447 if (e.hash == hash && Objects.equals(e.key, key) && Objects.equals(e.value, oldValue)) { 1448 e.value = newValue; 1449 e.recordAccess(this); 1450 return true; 1451 } 1452 } 1453 return false; 1454 } else if (table[i] != null) { 1455 TreeBin tb = ((TreeBin) table[i]); 1456 TreeNode p = tb.getTreeNode(hash, key); 1457 if (p != null) { 1458 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1459 // assert pEntry.key.equals(key); 1460 if (Objects.equals(pEntry.value, oldValue)) { 1461 pEntry.value = newValue; 1462 pEntry.recordAccess(this); 1463 return true; 1464 } 1465 } 1466 } 1467 return false; 1468 } 1469 1470 @Override 1471 public V replace(K key, V value) { 1472 if (isEmpty()) { 1473 return null; 1474 } 1475 if (key == null) { 1476 if (nullKeyEntry != null) { 1477 return putForNullKey(value); 1478 } 1479 return null; 1480 } 1481 int hash = hash(key); 1482 int i = indexFor(hash, table.length); 1483 if (table[i] instanceof Entry) { 1484 @SuppressWarnings("unchecked") 1485 Entry<K,V> e = (Entry<K,V>)table[i]; 1486 for (; e != null; e = (Entry<K,V>)e.next) { 1487 if (e.hash == hash && Objects.equals(e.key, key)) { 1488 V oldValue = e.value; 1489 e.value = value; 1490 e.recordAccess(this); 1491 return oldValue; 1492 } 1493 } 1494 1495 return null; 1496 } else if (table[i] != null) { 1497 TreeBin tb = ((TreeBin) table[i]); 1498 TreeNode p = tb.getTreeNode(hash, key); 1499 if (p != null) { 1500 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1501 // assert pEntry.key.equals(key); 1502 V oldValue = pEntry.value; 1503 pEntry.value = value; 1504 pEntry.recordAccess(this); 1505 return oldValue; 1506 } 1507 } 1508 return null; 1509 } 1510 1511 @Override 1512 public V computeIfAbsent(K key, Function<? super K, ? extends V> mappingFunction) { 1513 if (table == EMPTY_TABLE) { 1514 inflateTable(threshold); 1515 } 1516 if (key == null) { 1517 if (nullKeyEntry == null || nullKeyEntry.value == null) { 1518 V newValue = mappingFunction.apply(key); 1519 if (newValue != null) { 1520 putForNullKey(newValue); 1521 } 1522 return newValue; 1523 } 1524 return nullKeyEntry.value; 1525 } 1526 int hash = hash(key); 1527 int i = indexFor(hash, table.length); 1528 boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? 1529 1530 if (table[i] instanceof Entry) { 1531 int listSize = 0; 1532 @SuppressWarnings("unchecked") 1533 Entry<K,V> e = (Entry<K,V>)table[i]; 1534 for (; e != null; e = (Entry<K,V>)e.next) { 1535 if (e.hash == hash && Objects.equals(e.key, key)) { 1536 V oldValue = e.value; 1537 if (oldValue == null) { 1538 V newValue = mappingFunction.apply(key); 1539 if (newValue != null) { 1540 e.value = newValue; 1541 e.recordAccess(this); 1542 } 1543 return newValue; 1544 } 1545 return oldValue; 1546 } 1547 listSize++; 1548 } 1549 // Didn't find, fall through to call the mapping function 1550 checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; 1551 } else if (table[i] != null) { 1552 TreeBin e = (TreeBin)table[i]; 1553 V value = mappingFunction.apply(key); 1554 if (value == null) { // Return the existing value, if any 1555 TreeNode p = e.getTreeNode(hash, key); 1556 if (p != null) { 1557 return (V) p.entry.value; 1558 } 1559 return null; 1560 } else { // Put the new value into the Tree, if absent 1561 TreeNode p = e.putTreeNode(hash, key, value, null); 1562 if (p == null) { // not found, new node was added 1563 modCount++; 1564 size++; 1565 if (size >= threshold) { 1566 resize(2 * table.length); 1567 } 1568 return value; 1569 } else { // putTreeNode() found an existing node 1570 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1571 V oldVal = pEntry.value; 1572 if (oldVal == null) { // only replace if maps to null 1573 pEntry.value = value; 1574 pEntry.recordAccess(this); 1575 return value; 1576 } 1577 return oldVal; 1578 } 1579 } 1580 } 1581 V newValue = mappingFunction.apply(key); 1582 if (newValue != null) { // add Entry and check for TreeBin conversion 1583 modCount++; 1584 addEntry(hash, key, newValue, i, checkIfNeedTree); 1585 } 1586 1587 return newValue; 1588 } 1589 1590 @Override 1591 public V computeIfPresent(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 1592 if (isEmpty()) { 1593 return null; 1594 } 1595 if (key == null) { 1596 V oldValue; 1597 if (nullKeyEntry != null && (oldValue = nullKeyEntry.value) != null) { 1598 V newValue = remappingFunction.apply(key, oldValue); 1599 if (newValue != null ) { 1600 putForNullKey(newValue); 1601 return newValue; 1602 } else { 1603 removeNullKey(); 1604 } 1605 } 1606 return null; 1607 } 1608 int hash = hash(key); 1609 int i = indexFor(hash, table.length); 1610 if (table[i] instanceof Entry) { 1611 @SuppressWarnings("unchecked") 1612 Entry<K,V> prev = (Entry<K,V>)table[i]; 1613 Entry<K,V> e = prev; 1614 while (e != null) { 1615 Entry<K,V> next = (Entry<K,V>)e.next; 1616 if (e.hash == hash && Objects.equals(e.key, key)) { 1617 V oldValue = e.value; 1618 if (oldValue == null) 1619 break; 1620 V newValue = remappingFunction.apply(key, oldValue); 1621 if (newValue == null) { 1622 modCount++; 1623 size--; 1624 if (prev == e) 1625 table[i] = next; 1626 else 1627 prev.next = next; 1628 e.recordRemoval(this); 1629 } else { 1630 e.value = newValue; 1631 e.recordAccess(this); 1632 } 1633 return newValue; 1634 } 1635 prev = e; 1636 e = next; 1637 } 1638 } else if (table[i] != null) { 1639 TreeBin tb = (TreeBin)table[i]; 1640 TreeNode p = tb.getTreeNode(hash, key); 1641 if (p != null) { 1642 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1643 // assert pEntry.key.equals(key); 1644 V oldValue = pEntry.value; 1645 if (oldValue != null) { 1646 V newValue = remappingFunction.apply(key, oldValue); 1647 if (newValue == null) { // remove mapping 1648 modCount++; 1649 size--; 1650 tb.deleteTreeNode(p); 1651 pEntry.recordRemoval(this); 1652 if (tb.root == null || tb.first == null) { 1653 // assert tb.root == null && tb.first == null : 1654 // "TreeBin.first and root should both be null"; 1655 // TreeBin is now empty, we should blank this bin 1656 table[i] = null; 1657 } 1658 } else { 1659 pEntry.value = newValue; 1660 pEntry.recordAccess(this); 1661 } 1662 return newValue; 1663 } 1664 } 1665 } 1666 return null; 1667 } 1668 1669 @Override 1670 public V compute(K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) { 1671 if (table == EMPTY_TABLE) { 1672 inflateTable(threshold); 1673 } 1674 if (key == null) { 1675 V oldValue = nullKeyEntry == null ? null : nullKeyEntry.value; 1676 V newValue = remappingFunction.apply(key, oldValue); 1677 if (newValue != oldValue) { 1678 if (newValue == null) { 1679 removeNullKey(); 1680 } else { 1681 putForNullKey(newValue); 1682 } 1683 } 1684 return newValue; 1685 } 1686 int hash = hash(key); 1687 int i = indexFor(hash, table.length); 1688 boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? 1689 1690 if (table[i] instanceof Entry) { 1691 int listSize = 0; 1692 @SuppressWarnings("unchecked") 1693 Entry<K,V> prev = (Entry<K,V>)table[i]; 1694 Entry<K,V> e = prev; 1695 1696 while (e != null) { 1697 Entry<K,V> next = (Entry<K,V>)e.next; 1698 if (e.hash == hash && Objects.equals(e.key, key)) { 1699 V oldValue = e.value; 1700 V newValue = remappingFunction.apply(key, oldValue); 1701 if (newValue != oldValue) { 1702 if (newValue == null) { 1703 modCount++; 1704 size--; 1705 if (prev == e) 1706 table[i] = next; 1707 else 1708 prev.next = next; 1709 e.recordRemoval(this); 1710 } else { 1711 e.value = newValue; 1712 e.recordAccess(this); 1713 } 1714 } 1715 return newValue; 1716 } 1717 prev = e; 1718 e = next; 1719 listSize++; 1720 } 1721 checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; 1722 } else if (table[i] != null) { 1723 TreeBin tb = (TreeBin)table[i]; 1724 TreeNode p = tb.getTreeNode(hash, key); 1725 V oldValue = p == null ? null : (V)p.entry.value; 1726 V newValue = remappingFunction.apply(key, oldValue); 1727 if (newValue != oldValue) { 1728 if (newValue == null) { 1729 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1730 modCount++; 1731 size--; 1732 tb.deleteTreeNode(p); 1733 pEntry.recordRemoval(this); 1734 if (tb.root == null || tb.first == null) { 1735 // assert tb.root == null && tb.first == null : 1736 // "TreeBin.first and root should both be null"; 1737 // TreeBin is now empty, we should blank this bin 1738 table[i] = null; 1739 } 1740 } else { 1741 if (p != null) { // just update the value 1742 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1743 pEntry.value = newValue; 1744 pEntry.recordAccess(this); 1745 } else { // need to put new node 1746 p = tb.putTreeNode(hash, key, newValue, null); 1747 // assert p == null; // should have added a new node 1748 modCount++; 1749 size++; 1750 if (size >= threshold) { 1751 resize(2 * table.length); 1752 } 1753 } 1754 } 1755 } 1756 return newValue; 1757 } 1758 1759 V newValue = remappingFunction.apply(key, null); 1760 if (newValue != null) { 1761 modCount++; 1762 addEntry(hash, key, newValue, i, checkIfNeedTree); 1763 } 1764 1765 return newValue; 1766 } 1767 1768 @Override 1769 public V merge(K key, V value, BiFunction<? super V, ? super V, ? extends V> remappingFunction) { 1770 if (table == EMPTY_TABLE) { 1771 inflateTable(threshold); 1772 } 1773 if (key == null) { 1774 V oldValue = nullKeyEntry == null ? null : nullKeyEntry.value; 1775 V newValue = oldValue == null ? value : remappingFunction.apply(oldValue, value); 1776 if (newValue != null) { 1777 putForNullKey(newValue); 1778 } else if (nullKeyEntry != null) { 1779 removeNullKey(); 1780 } 1781 return newValue; 1782 } 1783 int hash = hash(key); 1784 int i = indexFor(hash, table.length); 1785 boolean checkIfNeedTree = false; // Might we convert bin to a TreeBin? 1786 1787 if (table[i] instanceof Entry) { 1788 int listSize = 0; 1789 @SuppressWarnings("unchecked") 1790 Entry<K,V> prev = (Entry<K,V>)table[i]; 1791 Entry<K,V> e = prev; 1792 1793 while (e != null) { 1794 Entry<K,V> next = (Entry<K,V>)e.next; 1795 if (e.hash == hash && Objects.equals(e.key, key)) { 1796 V oldValue = e.value; 1797 V newValue = (oldValue == null) ? value : 1798 remappingFunction.apply(oldValue, value); 1799 if (newValue == null) { 1800 modCount++; 1801 size--; 1802 if (prev == e) 1803 table[i] = next; 1804 else 1805 prev.next = next; 1806 e.recordRemoval(this); 1807 } else { 1808 e.value = newValue; 1809 e.recordAccess(this); 1810 } 1811 return newValue; 1812 } 1813 prev = e; 1814 e = next; 1815 listSize++; 1816 } 1817 // Didn't find, so fall through and (maybe) call addEntry() to add 1818 // the Entry and check for TreeBin conversion. 1819 checkIfNeedTree = listSize >= TreeBin.TREE_THRESHOLD; 1820 } else if (table[i] != null) { 1821 TreeBin tb = (TreeBin)table[i]; 1822 TreeNode p = tb.getTreeNode(hash, key); 1823 V oldValue = p == null ? null : (V)p.entry.value; 1824 V newValue = (oldValue == null) ? value : 1825 remappingFunction.apply(oldValue, value); 1826 if (newValue == null) { 1827 if (p != null) { 1828 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1829 modCount++; 1830 size--; 1831 tb.deleteTreeNode(p); 1832 pEntry.recordRemoval(this); 1833 1834 if (tb.root == null || tb.first == null) { 1835 // assert tb.root == null && tb.first == null : 1836 // "TreeBin.first and root should both be null"; 1837 // TreeBin is now empty, we should blank this bin 1838 table[i] = null; 1839 } 1840 } 1841 return null; 1842 } else if (newValue != oldValue) { 1843 if (p != null) { // just update the value 1844 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1845 pEntry.value = newValue; 1846 pEntry.recordAccess(this); 1847 } else { // need to put new node 1848 p = tb.putTreeNode(hash, key, newValue, null); 1849 // assert p == null; // should have added a new node 1850 modCount++; 1851 size++; 1852 if (size >= threshold) { 1853 resize(2 * table.length); 1854 } 1855 } 1856 } 1857 return newValue; 1858 } 1859 if (value != null) { 1860 modCount++; 1861 addEntry(hash, key, value, i, checkIfNeedTree); 1862 } 1863 return value; 1864 } 1865 1866 // end of optimized implementations of default methods in Map 1867 1868 /** 1869 * Removes and returns the entry associated with the specified key 1870 * in the HashMap. Returns null if the HashMap contains no mapping 1871 * for this key. 1872 * 1873 * We don't bother converting TreeBins back to Entry lists if the bin falls 1874 * back below TREE_THRESHOLD, but we do clear bins when removing the last 1875 * TreeNode in a TreeBin. 1876 */ 1877 final Entry<K,V> removeEntryForKey(Object key) { 1878 if (isEmpty()) { 1879 return null; 1880 } 1881 if (key == null) { 1882 if (nullKeyEntry != null) { 1883 return removeNullKey(); 1884 } 1885 return null; 1886 } 1887 int hash = hash(key); 1888 int i = indexFor(hash, table.length); 1889 1890 if (table[i] instanceof Entry) { 1891 @SuppressWarnings("unchecked") 1892 Entry<K,V> prev = (Entry<K,V>)table[i]; 1893 Entry<K,V> e = prev; 1894 1895 while (e != null) { 1896 @SuppressWarnings("unchecked") 1897 Entry<K,V> next = (Entry<K,V>) e.next; 1898 if (e.hash == hash && Objects.equals(e.key, key)) { 1899 modCount++; 1900 size--; 1901 if (prev == e) 1902 table[i] = next; 1903 else 1904 prev.next = next; 1905 e.recordRemoval(this); 1906 return e; 1907 } 1908 prev = e; 1909 e = next; 1910 } 1911 } else if (table[i] != null) { 1912 TreeBin tb = ((TreeBin) table[i]); 1913 TreeNode p = tb.getTreeNode(hash, (K)key); 1914 if (p != null) { 1915 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1916 // assert pEntry.key.equals(key); 1917 modCount++; 1918 size--; 1919 tb.deleteTreeNode(p); 1920 pEntry.recordRemoval(this); 1921 if (tb.root == null || tb.first == null) { 1922 // assert tb.root == null && tb.first == null : 1923 // "TreeBin.first and root should both be null"; 1924 // TreeBin is now empty, we should blank this bin 1925 table[i] = null; 1926 } 1927 return pEntry; 1928 } 1929 } 1930 return null; 1931 } 1932 1933 /** 1934 * Special version of remove for EntrySet using {@code Map.Entry.equals()} 1935 * for matching. 1936 */ 1937 final Entry<K,V> removeMapping(Object o) { 1938 if (isEmpty() || !(o instanceof Map.Entry)) 1939 return null; 1940 1941 Map.Entry<?,?> entry = (Map.Entry<?,?>) o; 1942 Object key = entry.getKey(); 1943 1944 if (key == null) { 1945 if (entry.equals(nullKeyEntry)) { 1946 return removeNullKey(); 1947 } 1948 return null; 1949 } 1950 1951 int hash = hash(key); 1952 int i = indexFor(hash, table.length); 1953 1954 if (table[i] instanceof Entry) { 1955 @SuppressWarnings("unchecked") 1956 Entry<K,V> prev = (Entry<K,V>)table[i]; 1957 Entry<K,V> e = prev; 1958 1959 while (e != null) { 1960 @SuppressWarnings("unchecked") 1961 Entry<K,V> next = (Entry<K,V>)e.next; 1962 if (e.hash == hash && e.equals(entry)) { 1963 modCount++; 1964 size--; 1965 if (prev == e) 1966 table[i] = next; 1967 else 1968 prev.next = next; 1969 e.recordRemoval(this); 1970 return e; 1971 } 1972 prev = e; 1973 e = next; 1974 } 1975 } else if (table[i] != null) { 1976 TreeBin tb = ((TreeBin) table[i]); 1977 TreeNode p = tb.getTreeNode(hash, (K)key); 1978 if (p != null && p.entry.equals(entry)) { 1979 @SuppressWarnings("unchecked") 1980 Entry<K,V> pEntry = (Entry<K,V>)p.entry; 1981 // assert pEntry.key.equals(key); 1982 modCount++; 1983 size--; 1984 tb.deleteTreeNode(p); 1985 pEntry.recordRemoval(this); 1986 if (tb.root == null || tb.first == null) { 1987 // assert tb.root == null && tb.first == null : 1988 // "TreeBin.first and root should both be null"; 1989 // TreeBin is now empty, we should blank this bin 1990 table[i] = null; 1991 } 1992 return pEntry; 1993 } 1994 } 1995 return null; 1996 } 1997 1998 /* 1999 * Remove the mapping for the null key, and update internal accounting 2000 * (size, modcount, recordRemoval, etc). 2001 * 2002 * Assumes nullKeyEntry is non-null. 2003 */ 2004 private Entry<K,V> removeNullKey() { 2005 // assert nullKeyEntry != null; 2006 Entry<K,V> retVal = nullKeyEntry; 2007 modCount++; 2008 size--; 2009 retVal.recordRemoval(this); 2010 nullKeyEntry = null; 2011 return retVal; 2012 } 2013 2014 /** 2015 * Removes all of the mappings from this map. 2016 * The map will be empty after this call returns. 2017 */ 2018 public void clear() { 2019 modCount++; 2020 if (nullKeyEntry != null) { 2021 nullKeyEntry = null; 2022 } 2023 Arrays.fill(table, null); 2024 size = 0; 2025 } 2026 2027 /** 2028 * Returns <tt>true</tt> if this map maps one or more keys to the 2029 * specified value. 2030 * 2031 * @param value value whose presence in this map is to be tested 2032 * @return <tt>true</tt> if this map maps one or more keys to the 2033 * specified value 2034 */ 2035 public boolean containsValue(Object value) { 2036 if (value == null) { 2037 return containsNullValue(); 2038 } 2039 Object[] tab = table; 2040 for (int i = 0; i < tab.length; i++) { 2041 if (tab[i] instanceof Entry) { 2042 Entry<?,?> e = (Entry<?,?>)tab[i]; 2043 for (; e != null; e = (Entry<?,?>)e.next) { 2044 if (value.equals(e.value)) { 2045 return true; 2046 } 2047 } 2048 } else if (tab[i] != null) { 2049 TreeBin e = (TreeBin)tab[i]; 2050 TreeNode p = e.first; 2051 for (; p != null; p = (TreeNode) p.entry.next) { 2052 if (value == p.entry.value || value.equals(p.entry.value)) { 2053 return true; 2054 } 2055 } 2056 } 2057 } 2058 // Didn't find value in table - could be in nullKeyEntry 2059 return (nullKeyEntry != null && (value == nullKeyEntry.value || 2060 value.equals(nullKeyEntry.value))); 2061 } 2062 2063 /** 2064 * Special-case code for containsValue with null argument 2065 */ 2066 private boolean containsNullValue() { 2067 Object[] tab = table; 2068 for (int i = 0; i < tab.length; i++) { 2069 if (tab[i] instanceof Entry) { 2070 Entry<K,V> e = (Entry<K,V>)tab[i]; 2071 for (; e != null; e = (Entry<K,V>)e.next) { 2072 if (e.value == null) { 2073 return true; 2074 } 2075 } 2076 } else if (tab[i] != null) { 2077 TreeBin e = (TreeBin)tab[i]; 2078 TreeNode p = e.first; 2079 for (; p != null; p = (TreeNode) p.entry.next) { 2080 if (p.entry.value == null) { 2081 return true; 2082 } 2083 } 2084 } 2085 } 2086 // Didn't find value in table - could be in nullKeyEntry 2087 return (nullKeyEntry != null && nullKeyEntry.value == null); 2088 } 2089 2090 /** 2091 * Returns a shallow copy of this <tt>HashMap</tt> instance: the keys and 2092 * values themselves are not cloned. 2093 * 2094 * @return a shallow copy of this map 2095 */ 2096 @SuppressWarnings("unchecked") 2097 public Object clone() { 2098 HashMap<K,V> result = null; 2099 try { 2100 result = (HashMap<K,V>)super.clone(); 2101 } catch (CloneNotSupportedException e) { 2102 // assert false; 2103 } 2104 if (result.table != EMPTY_TABLE) { 2105 result.inflateTable(Math.min( 2106 (int) Math.min( 2107 size * Math.min(1 / loadFactor, 4.0f), 2108 // we have limits... 2109 HashMap.MAXIMUM_CAPACITY), 2110 table.length)); 2111 } 2112 result.entrySet = null; 2113 result.modCount = 0; 2114 result.size = 0; 2115 result.nullKeyEntry = null; 2116 result.init(); 2117 result.putAllForCreate(this); 2118 2119 return result; 2120 } 2121 2122 static class Entry<K,V> implements Map.Entry<K,V> { 2123 final K key; 2124 V value; 2125 Object next; // an Entry, or a TreeNode 2126 final int hash; 2127 2128 /** 2129 * Creates new entry. 2130 */ 2131 Entry(int h, K k, V v, Object n) { 2132 value = v; 2133 next = n; 2134 key = k; 2135 hash = h; 2136 } 2137 2138 public final K getKey() { 2139 return key; 2140 } 2141 2142 public final V getValue() { 2143 return value; 2144 } 2145 2146 public final V setValue(V newValue) { 2147 V oldValue = value; 2148 value = newValue; 2149 return oldValue; 2150 } 2151 2152 public final boolean equals(Object o) { 2153 if (!(o instanceof Map.Entry)) 2154 return false; 2155 Map.Entry<?,?> e = (Map.Entry<?,?>)o; 2156 Object k1 = getKey(); 2157 Object k2 = e.getKey(); 2158 if (k1 == k2 || (k1 != null && k1.equals(k2))) { 2159 Object v1 = getValue(); 2160 Object v2 = e.getValue(); 2161 if (v1 == v2 || (v1 != null && v1.equals(v2))) 2162 return true; 2163 } 2164 return false; 2165 } 2166 2167 public final int hashCode() { 2168 return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue()); 2169 } 2170 2171 public final String toString() { 2172 return getKey() + "=" + getValue(); 2173 } 2174 2175 /** 2176 * This method is invoked whenever the value in an entry is 2177 * overwritten for a key that's already in the HashMap. 2178 */ 2179 void recordAccess(HashMap<K,V> m) { 2180 } 2181 2182 /** 2183 * This method is invoked whenever the entry is 2184 * removed from the table. 2185 */ 2186 void recordRemoval(HashMap<K,V> m) { 2187 } 2188 } 2189 2190 void addEntry(int hash, K key, V value, int bucketIndex) { 2191 addEntry(hash, key, value, bucketIndex, true); 2192 } 2193 2194 /** 2195 * Adds a new entry with the specified key, value and hash code to 2196 * the specified bucket. It is the responsibility of this 2197 * method to resize the table if appropriate. The new entry is then 2198 * created by calling createEntry(). 2199 * 2200 * Subclass overrides this to alter the behavior of put method. 2201 * 2202 * If checkIfNeedTree is false, it is known that this bucket will not need 2203 * to be converted to a TreeBin, so don't bothering checking. 2204 * 2205 * Assumes key is not null. 2206 */ 2207 void addEntry(int hash, K key, V value, int bucketIndex, boolean checkIfNeedTree) { 2208 // assert key != null; 2209 if ((size >= threshold) && (null != table[bucketIndex])) { 2210 resize(2 * table.length); 2211 hash = hash(key); 2212 bucketIndex = indexFor(hash, table.length); 2213 } 2214 createEntry(hash, key, value, bucketIndex, checkIfNeedTree); 2215 } 2216 2217 /** 2218 * Called by addEntry(), and also used when creating entries 2219 * as part of Map construction or "pseudo-construction" (cloning, 2220 * deserialization). This version does not check for resizing of the table. 2221 * 2222 * This method is responsible for converting a bucket to a TreeBin once 2223 * TREE_THRESHOLD is reached. However if checkIfNeedTree is false, it is known 2224 * that this bucket will not need to be converted to a TreeBin, so don't 2225 * bother checking. The new entry is constructed by calling newEntry(). 2226 * 2227 * Assumes key is not null. 2228 * 2229 * Note: buckets already converted to a TreeBin don't call this method, but 2230 * instead call TreeBin.putTreeNode() to create new entries. 2231 */ 2232 void createEntry(int hash, K key, V value, int bucketIndex, boolean checkIfNeedTree) { 2233 // assert key != null; 2234 @SuppressWarnings("unchecked") 2235 Entry<K,V> e = (Entry<K,V>)table[bucketIndex]; 2236 table[bucketIndex] = newEntry(hash, key, value, e); 2237 size++; 2238 2239 if (checkIfNeedTree) { 2240 int listSize = 0; 2241 for (e = (Entry<K,V>) table[bucketIndex]; e != null; e = (Entry<K,V>)e.next) { 2242 listSize++; 2243 if (listSize >= TreeBin.TREE_THRESHOLD) { // Convert to TreeBin 2244 if (comparableClassFor(key) != null) { 2245 TreeBin t = new TreeBin(); 2246 t.populate((Entry)table[bucketIndex]); 2247 table[bucketIndex] = t; 2248 } 2249 break; 2250 } 2251 } 2252 } 2253 } 2254 2255 /* 2256 * Factory method to create a new Entry object. 2257 */ 2258 Entry<K,V> newEntry(int hash, K key, V value, Object next) { 2259 return new HashMap.Entry<>(hash, key, value, next); 2260 } 2261 2262 2263 private abstract class HashIterator<E> implements Iterator<E> { 2264 Object next; // next entry to return, an Entry or a TreeNode 2265 int expectedModCount; // For fast-fail 2266 int index; // current slot 2267 Object current; // current entry, an Entry or a TreeNode 2268 2269 HashIterator() { 2270 expectedModCount = modCount; 2271 if (size > 0) { // advance to first entry 2272 if (nullKeyEntry != null) { 2273 // assert nullKeyEntry.next == null; 2274 // This works with nextEntry(): nullKeyEntry isa Entry, and 2275 // e.next will be null, so we'll hit the findNextBin() call. 2276 next = nullKeyEntry; 2277 } else { 2278 findNextBin(); 2279 } 2280 } 2281 } 2282 2283 public final boolean hasNext() { 2284 return next != null; 2285 } 2286 2287 @SuppressWarnings("unchecked") 2288 final Entry<K,V> nextEntry() { 2289 if (modCount != expectedModCount) { 2290 throw new ConcurrentModificationException(); 2291 } 2292 Object e = next; 2293 Entry<K,V> retVal; 2294 2295 if (e == null) 2296 throw new NoSuchElementException(); 2297 2298 if (e instanceof Entry) { 2299 retVal = (Entry<K,V>)e; 2300 next = ((Entry<K,V>)e).next; 2301 } else { // TreeBin 2302 retVal = (Entry<K,V>)((TreeNode)e).entry; 2303 next = retVal.next; 2304 } 2305 2306 if (next == null) { // Move to next bin 2307 findNextBin(); 2308 } 2309 current = e; 2310 return retVal; 2311 } 2312 2313 public void remove() { 2314 if (current == null) 2315 throw new IllegalStateException(); 2316 if (modCount != expectedModCount) 2317 throw new ConcurrentModificationException(); 2318 K k; 2319 2320 if (current instanceof Entry) { 2321 k = ((Entry<K,V>)current).key; 2322 } else { 2323 k = ((Entry<K,V>)((TreeNode)current).entry).key; 2324 2325 } 2326 current = null; 2327 HashMap.this.removeEntryForKey(k); 2328 expectedModCount = modCount; 2329 } 2330 2331 /* 2332 * Set 'next' to the first entry of the next non-empty bin in the table 2333 */ 2334 private void findNextBin() { 2335 // assert next == null; 2336 Object[] t = table; 2337 2338 while (index < t.length && (next = t[index++]) == null) 2339 ; 2340 if (next instanceof HashMap.TreeBin) { // Point to the first TreeNode 2341 next = ((TreeBin) next).first; 2342 // assert next != null; // There should be no empty TreeBins 2343 } 2344 } 2345 } 2346 2347 private final class ValueIterator extends HashIterator<V> { 2348 public V next() { 2349 return nextEntry().value; 2350 } 2351 } 2352 2353 private final class KeyIterator extends HashIterator<K> { 2354 public K next() { 2355 return nextEntry().getKey(); 2356 } 2357 } 2358 2359 private final class EntryIterator extends HashIterator<Map.Entry<K,V>> { 2360 public Map.Entry<K,V> next() { 2361 return nextEntry(); 2362 } 2363 } 2364 2365 // Subclass overrides these to alter behavior of views' iterator() method 2366 Iterator<K> newKeyIterator() { 2367 return new KeyIterator(); 2368 } 2369 Iterator<V> newValueIterator() { 2370 return new ValueIterator(); 2371 } 2372 Iterator<Map.Entry<K,V>> newEntryIterator() { 2373 return new EntryIterator(); 2374 } 2375 2376 2377 // Views 2378 2379 private transient Set<Map.Entry<K,V>> entrySet = null; 2380 2381 /** 2382 * Returns a {@link Set} view of the keys contained in this map. 2383 * The set is backed by the map, so changes to the map are 2384 * reflected in the set, and vice-versa. If the map is modified 2385 * while an iteration over the set is in progress (except through 2386 * the iterator's own <tt>remove</tt> operation), the results of 2387 * the iteration are undefined. The set supports element removal, 2388 * which removes the corresponding mapping from the map, via the 2389 * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>, 2390 * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt> 2391 * operations. It does not support the <tt>add</tt> or <tt>addAll</tt> 2392 * operations. 2393 */ 2394 public Set<K> keySet() { 2395 Set<K> ks = keySet; 2396 return (ks != null ? ks : (keySet = new KeySet())); 2397 } 2398 2399 private final class KeySet extends AbstractSet<K> { 2400 public Iterator<K> iterator() { 2401 return newKeyIterator(); 2402 } 2403 public int size() { 2404 return size; 2405 } 2406 public boolean contains(Object o) { 2407 return containsKey(o); 2408 } 2409 public boolean remove(Object o) { 2410 return HashMap.this.removeEntryForKey(o) != null; 2411 } 2412 public void clear() { 2413 HashMap.this.clear(); 2414 } 2415 2416 public Spliterator<K> spliterator() { 2417 if (HashMap.this.getClass() == HashMap.class) 2418 return new KeySpliterator<K,V>(HashMap.this, 0, -1, 0, 0); 2419 else 2420 return Spliterators.spliterator 2421 (this, Spliterator.SIZED | Spliterator.DISTINCT); 2422 } 2423 } 2424 2425 /** 2426 * Returns a {@link Collection} view of the values contained in this map. 2427 * The collection is backed by the map, so changes to the map are 2428 * reflected in the collection, and vice-versa. If the map is 2429 * modified while an iteration over the collection is in progress 2430 * (except through the iterator's own <tt>remove</tt> operation), 2431 * the results of the iteration are undefined. The collection 2432 * supports element removal, which removes the corresponding 2433 * mapping from the map, via the <tt>Iterator.remove</tt>, 2434 * <tt>Collection.remove</tt>, <tt>removeAll</tt>, 2435 * <tt>retainAll</tt> and <tt>clear</tt> operations. It does not 2436 * support the <tt>add</tt> or <tt>addAll</tt> operations. 2437 */ 2438 public Collection<V> values() { 2439 Collection<V> vs = values; 2440 return (vs != null ? vs : (values = new Values())); 2441 } 2442 2443 private final class Values extends AbstractCollection<V> { 2444 public Iterator<V> iterator() { 2445 return newValueIterator(); 2446 } 2447 public int size() { 2448 return size; 2449 } 2450 public boolean contains(Object o) { 2451 return containsValue(o); 2452 } 2453 public void clear() { 2454 HashMap.this.clear(); 2455 } 2456 2457 public Spliterator<V> spliterator() { 2458 if (HashMap.this.getClass() == HashMap.class) 2459 return new ValueSpliterator<K,V>(HashMap.this, 0, -1, 0, 0); 2460 else 2461 return Spliterators.spliterator 2462 (this, Spliterator.SIZED); 2463 } 2464 } 2465 2466 /** 2467 * Returns a {@link Set} view of the mappings contained in this map. 2468 * The set is backed by the map, so changes to the map are 2469 * reflected in the set, and vice-versa. If the map is modified 2470 * while an iteration over the set is in progress (except through 2471 * the iterator's own <tt>remove</tt> operation, or through the 2472 * <tt>setValue</tt> operation on a map entry returned by the 2473 * iterator) the results of the iteration are undefined. The set 2474 * supports element removal, which removes the corresponding 2475 * mapping from the map, via the <tt>Iterator.remove</tt>, 2476 * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and 2477 * <tt>clear</tt> operations. It does not support the 2478 * <tt>add</tt> or <tt>addAll</tt> operations. 2479 * 2480 * @return a set view of the mappings contained in this map 2481 */ 2482 public Set<Map.Entry<K,V>> entrySet() { 2483 return entrySet0(); 2484 } 2485 2486 private Set<Map.Entry<K,V>> entrySet0() { 2487 Set<Map.Entry<K,V>> es = entrySet; 2488 return es != null ? es : (entrySet = new EntrySet()); 2489 } 2490 2491 private final class EntrySet extends AbstractSet<Map.Entry<K,V>> { 2492 public Iterator<Map.Entry<K,V>> iterator() { 2493 return newEntryIterator(); 2494 } 2495 public boolean contains(Object o) { 2496 if (!(o instanceof Map.Entry)) 2497 return false; 2498 Map.Entry<?,?> e = (Map.Entry<?,?>) o; 2499 Entry<K,V> candidate = getEntry(e.getKey()); 2500 return candidate != null && candidate.equals(e); 2501 } 2502 public boolean remove(Object o) { 2503 return removeMapping(o) != null; 2504 } 2505 public int size() { 2506 return size; 2507 } 2508 public void clear() { 2509 HashMap.this.clear(); 2510 } 2511 2512 public Spliterator<Map.Entry<K,V>> spliterator() { 2513 if (HashMap.this.getClass() == HashMap.class) 2514 return new EntrySpliterator<K,V>(HashMap.this, 0, -1, 0, 0); 2515 else 2516 return Spliterators.spliterator 2517 (this, Spliterator.SIZED | Spliterator.DISTINCT); 2518 } 2519 } 2520 2521 /** 2522 * Save the state of the <tt>HashMap</tt> instance to a stream (i.e., 2523 * serialize it). 2524 * 2525 * @serialData The <i>capacity</i> of the HashMap (the length of the 2526 * bucket array) is emitted (int), followed by the 2527 * <i>size</i> (an int, the number of key-value 2528 * mappings), followed by the key (Object) and value (Object) 2529 * for each key-value mapping. The key-value mappings are 2530 * emitted in no particular order. 2531 */ 2532 private void writeObject(java.io.ObjectOutputStream s) 2533 throws IOException 2534 { 2535 // Write out the threshold, loadfactor, and any hidden stuff 2536 s.defaultWriteObject(); 2537 2538 // Write out number of buckets 2539 if (table==EMPTY_TABLE) { 2540 s.writeInt(roundUpToPowerOf2(threshold)); 2541 } else { 2542 s.writeInt(table.length); 2543 } 2544 2545 // Write out size (number of Mappings) 2546 s.writeInt(size); 2547 2548 // Write out keys and values (alternating) 2549 if (size > 0) { 2550 for(Map.Entry<K,V> e : entrySet0()) { 2551 s.writeObject(e.getKey()); 2552 s.writeObject(e.getValue()); 2553 } 2554 } 2555 } 2556 2557 private static final long serialVersionUID = 362498820763181265L; 2558 2559 /** 2560 * Reconstitute the {@code HashMap} instance from a stream (i.e., 2561 * deserialize it). 2562 */ 2563 private void readObject(java.io.ObjectInputStream s) 2564 throws IOException, ClassNotFoundException 2565 { 2566 // Read in the threshold (ignored), loadfactor, and any hidden stuff 2567 s.defaultReadObject(); 2568 if (loadFactor <= 0 || Float.isNaN(loadFactor)) { 2569 throw new InvalidObjectException("Illegal load factor: " + 2570 loadFactor); 2571 } 2572 2573 // set other fields that need values 2574 if (Holder.USE_HASHSEED) { 2575 Holder.UNSAFE.putIntVolatile(this, Holder.HASHSEED_OFFSET, 2576 sun.misc.Hashing.randomHashSeed(this)); 2577 } 2578 table = EMPTY_TABLE; 2579 2580 // Read in number of buckets 2581 s.readInt(); // ignored. 2582 2583 // Read number of mappings 2584 int mappings = s.readInt(); 2585 if (mappings < 0) 2586 throw new InvalidObjectException("Illegal mappings count: " + 2587 mappings); 2588 2589 // capacity chosen by number of mappings and desired load (if >= 0.25) 2590 int capacity = (int) Math.min( 2591 mappings * Math.min(1 / loadFactor, 4.0f), 2592 // we have limits... 2593 HashMap.MAXIMUM_CAPACITY); 2594 2595 // allocate the bucket array; 2596 if (mappings > 0) { 2597 inflateTable(capacity); 2598 } else { 2599 threshold = capacity; 2600 } 2601 2602 init(); // Give subclass a chance to do its thing. 2603 2604 // Read the keys and values, and put the mappings in the HashMap 2605 for (int i=0; i<mappings; i++) { 2606 @SuppressWarnings("unchecked") 2607 K key = (K) s.readObject(); 2608 @SuppressWarnings("unchecked") 2609 V value = (V) s.readObject(); 2610 putForCreate(key, value); 2611 } 2612 } 2613 2614 // These methods are used when serializing HashSets 2615 int capacity() { return table.length; } 2616 float loadFactor() { return loadFactor; } 2617 2618 /** 2619 * Standin until HM overhaul; based loosely on Weak and Identity HM. 2620 */ 2621 static class HashMapSpliterator<K,V> { 2622 final HashMap<K,V> map; 2623 Object current; // current node, can be Entry or TreeNode 2624 int index; // current index, modified on advance/split 2625 int fence; // one past last index 2626 int est; // size estimate 2627 int expectedModCount; // for comodification checks 2628 boolean acceptedNull; // Have we accepted the null key? 2629 // Without this, we can't distinguish 2630 // between being at the very beginning (and 2631 // needing to accept null), or being at the 2632 // end of the list in bin 0. In both cases, 2633 // current == null && index == 0. 2634 2635 HashMapSpliterator(HashMap<K,V> m, int origin, 2636 int fence, int est, 2637 int expectedModCount) { 2638 this.map = m; 2639 this.index = origin; 2640 this.fence = fence; 2641 this.est = est; 2642 this.expectedModCount = expectedModCount; 2643 this.acceptedNull = false; 2644 } 2645 2646 final int getFence() { // initialize fence and size on first use 2647 int hi; 2648 if ((hi = fence) < 0) { 2649 HashMap<K,V> m = map; 2650 est = m.size; 2651 expectedModCount = m.modCount; 2652 hi = fence = m.table.length; 2653 } 2654 return hi; 2655 } 2656 2657 public final long estimateSize() { 2658 getFence(); // force init 2659 return (long) est; 2660 } 2661 } 2662 2663 static final class KeySpliterator<K,V> 2664 extends HashMapSpliterator<K,V> 2665 implements Spliterator<K> { 2666 KeySpliterator(HashMap<K,V> m, int origin, int fence, int est, 2667 int expectedModCount) { 2668 super(m, origin, fence, est, expectedModCount); 2669 } 2670 2671 public KeySpliterator<K,V> trySplit() { 2672 int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; 2673 if (lo >= mid || current != null) { 2674 return null; 2675 } else { 2676 KeySpliterator<K,V> retVal = new KeySpliterator<K,V>(map, lo, 2677 index = mid, est >>>= 1, expectedModCount); 2678 // Only 'this' Spliterator chould check for null. 2679 retVal.acceptedNull = true; 2680 return retVal; 2681 } 2682 } 2683 2684 @SuppressWarnings("unchecked") 2685 public void forEachRemaining(Consumer<? super K> action) { 2686 int i, hi, mc; 2687 if (action == null) 2688 throw new NullPointerException(); 2689 HashMap<K,V> m = map; 2690 Object[] tab = m.table; 2691 if ((hi = fence) < 0) { 2692 mc = expectedModCount = m.modCount; 2693 hi = fence = tab.length; 2694 } 2695 else 2696 mc = expectedModCount; 2697 2698 if (!acceptedNull) { 2699 acceptedNull = true; 2700 if (m.nullKeyEntry != null) { 2701 action.accept(m.nullKeyEntry.key); 2702 } 2703 } 2704 if (tab.length >= hi && (i = index) >= 0 && i < (index = hi)) { 2705 Object p = current; 2706 do { 2707 if (p == null) { 2708 p = tab[i++]; 2709 if (p instanceof HashMap.TreeBin) { 2710 p = ((HashMap.TreeBin)p).first; 2711 } 2712 } else { 2713 HashMap.Entry<K,V> entry; 2714 if (p instanceof HashMap.Entry) { 2715 entry = (HashMap.Entry<K,V>)p; 2716 } else { 2717 entry = (HashMap.Entry<K,V>)((TreeNode)p).entry; 2718 } 2719 action.accept(entry.key); 2720 p = entry.next; 2721 } 2722 } while (p != null || i < hi); 2723 if (m.modCount != mc) 2724 throw new ConcurrentModificationException(); 2725 } 2726 } 2727 2728 @SuppressWarnings("unchecked") 2729 public boolean tryAdvance(Consumer<? super K> action) { 2730 int hi; 2731 if (action == null) 2732 throw new NullPointerException(); 2733 Object[] tab = map.table; 2734 hi = getFence(); 2735 2736 if (!acceptedNull) { 2737 acceptedNull = true; 2738 if (map.nullKeyEntry != null) { 2739 action.accept(map.nullKeyEntry.key); 2740 if (map.modCount != expectedModCount) 2741 throw new ConcurrentModificationException(); 2742 return true; 2743 } 2744 } 2745 if (tab.length >= hi && index >= 0) { 2746 while (current != null || index < hi) { 2747 if (current == null) { 2748 current = tab[index++]; 2749 if (current instanceof HashMap.TreeBin) { 2750 current = ((HashMap.TreeBin)current).first; 2751 } 2752 } else { 2753 HashMap.Entry<K,V> entry; 2754 if (current instanceof HashMap.Entry) { 2755 entry = (HashMap.Entry<K,V>)current; 2756 } else { 2757 entry = (HashMap.Entry<K,V>)((TreeNode)current).entry; 2758 } 2759 K k = entry.key; 2760 current = entry.next; 2761 action.accept(k); 2762 if (map.modCount != expectedModCount) 2763 throw new ConcurrentModificationException(); 2764 return true; 2765 } 2766 } 2767 } 2768 return false; 2769 } 2770 2771 public int characteristics() { 2772 return (fence < 0 || est == map.size ? Spliterator.SIZED : 0) | 2773 Spliterator.DISTINCT; 2774 } 2775 } 2776 2777 static final class ValueSpliterator<K,V> 2778 extends HashMapSpliterator<K,V> 2779 implements Spliterator<V> { 2780 ValueSpliterator(HashMap<K,V> m, int origin, int fence, int est, 2781 int expectedModCount) { 2782 super(m, origin, fence, est, expectedModCount); 2783 } 2784 2785 public ValueSpliterator<K,V> trySplit() { 2786 int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; 2787 if (lo >= mid || current != null) { 2788 return null; 2789 } else { 2790 ValueSpliterator<K,V> retVal = new ValueSpliterator<K,V>(map, 2791 lo, index = mid, est >>>= 1, expectedModCount); 2792 // Only 'this' Spliterator chould check for null. 2793 retVal.acceptedNull = true; 2794 return retVal; 2795 } 2796 } 2797 2798 @SuppressWarnings("unchecked") 2799 public void forEachRemaining(Consumer<? super V> action) { 2800 int i, hi, mc; 2801 if (action == null) 2802 throw new NullPointerException(); 2803 HashMap<K,V> m = map; 2804 Object[] tab = m.table; 2805 if ((hi = fence) < 0) { 2806 mc = expectedModCount = m.modCount; 2807 hi = fence = tab.length; 2808 } 2809 else 2810 mc = expectedModCount; 2811 2812 if (!acceptedNull) { 2813 acceptedNull = true; 2814 if (m.nullKeyEntry != null) { 2815 action.accept(m.nullKeyEntry.value); 2816 } 2817 } 2818 if (tab.length >= hi && (i = index) >= 0 && i < (index = hi)) { 2819 Object p = current; 2820 do { 2821 if (p == null) { 2822 p = tab[i++]; 2823 if (p instanceof HashMap.TreeBin) { 2824 p = ((HashMap.TreeBin)p).first; 2825 } 2826 } else { 2827 HashMap.Entry<K,V> entry; 2828 if (p instanceof HashMap.Entry) { 2829 entry = (HashMap.Entry<K,V>)p; 2830 } else { 2831 entry = (HashMap.Entry<K,V>)((TreeNode)p).entry; 2832 } 2833 action.accept(entry.value); 2834 p = entry.next; 2835 } 2836 } while (p != null || i < hi); 2837 if (m.modCount != mc) 2838 throw new ConcurrentModificationException(); 2839 } 2840 } 2841 2842 @SuppressWarnings("unchecked") 2843 public boolean tryAdvance(Consumer<? super V> action) { 2844 int hi; 2845 if (action == null) 2846 throw new NullPointerException(); 2847 Object[] tab = map.table; 2848 hi = getFence(); 2849 2850 if (!acceptedNull) { 2851 acceptedNull = true; 2852 if (map.nullKeyEntry != null) { 2853 action.accept(map.nullKeyEntry.value); 2854 if (map.modCount != expectedModCount) 2855 throw new ConcurrentModificationException(); 2856 return true; 2857 } 2858 } 2859 if (tab.length >= hi && index >= 0) { 2860 while (current != null || index < hi) { 2861 if (current == null) { 2862 current = tab[index++]; 2863 if (current instanceof HashMap.TreeBin) { 2864 current = ((HashMap.TreeBin)current).first; 2865 } 2866 } else { 2867 HashMap.Entry<K,V> entry; 2868 if (current instanceof HashMap.Entry) { 2869 entry = (Entry<K,V>)current; 2870 } else { 2871 entry = (Entry<K,V>)((TreeNode)current).entry; 2872 } 2873 V v = entry.value; 2874 current = entry.next; 2875 action.accept(v); 2876 if (map.modCount != expectedModCount) 2877 throw new ConcurrentModificationException(); 2878 return true; 2879 } 2880 } 2881 } 2882 return false; 2883 } 2884 2885 public int characteristics() { 2886 return (fence < 0 || est == map.size ? Spliterator.SIZED : 0); 2887 } 2888 } 2889 2890 static final class EntrySpliterator<K,V> 2891 extends HashMapSpliterator<K,V> 2892 implements Spliterator<Map.Entry<K,V>> { 2893 EntrySpliterator(HashMap<K,V> m, int origin, int fence, int est, 2894 int expectedModCount) { 2895 super(m, origin, fence, est, expectedModCount); 2896 } 2897 2898 public EntrySpliterator<K,V> trySplit() { 2899 int hi = getFence(), lo = index, mid = (lo + hi) >>> 1; 2900 if (lo >= mid || current != null) { 2901 return null; 2902 } else { 2903 EntrySpliterator<K,V> retVal = new EntrySpliterator<K,V>(map, 2904 lo, index = mid, est >>>= 1, expectedModCount); 2905 // Only 'this' Spliterator chould check for null. 2906 retVal.acceptedNull = true; 2907 return retVal; 2908 } 2909 } 2910 2911 @SuppressWarnings("unchecked") 2912 public void forEachRemaining(Consumer<? super Map.Entry<K,V>> action) { 2913 int i, hi, mc; 2914 if (action == null) 2915 throw new NullPointerException(); 2916 HashMap<K,V> m = map; 2917 Object[] tab = m.table; 2918 if ((hi = fence) < 0) { 2919 mc = expectedModCount = m.modCount; 2920 hi = fence = tab.length; 2921 } 2922 else 2923 mc = expectedModCount; 2924 2925 if (!acceptedNull) { 2926 acceptedNull = true; 2927 if (m.nullKeyEntry != null) { 2928 action.accept(m.nullKeyEntry); 2929 } 2930 } 2931 if (tab.length >= hi && (i = index) >= 0 && i < (index = hi)) { 2932 Object p = current; 2933 do { 2934 if (p == null) { 2935 p = tab[i++]; 2936 if (p instanceof HashMap.TreeBin) { 2937 p = ((HashMap.TreeBin)p).first; 2938 } 2939 } else { 2940 HashMap.Entry<K,V> entry; 2941 if (p instanceof HashMap.Entry) { 2942 entry = (HashMap.Entry<K,V>)p; 2943 } else { 2944 entry = (HashMap.Entry<K,V>)((TreeNode)p).entry; 2945 } 2946 action.accept(entry); 2947 p = entry.next; 2948 2949 } 2950 } while (p != null || i < hi); 2951 if (m.modCount != mc) 2952 throw new ConcurrentModificationException(); 2953 } 2954 } 2955 2956 @SuppressWarnings("unchecked") 2957 public boolean tryAdvance(Consumer<? super Map.Entry<K,V>> action) { 2958 int hi; 2959 if (action == null) 2960 throw new NullPointerException(); 2961 Object[] tab = map.table; 2962 hi = getFence(); 2963 2964 if (!acceptedNull) { 2965 acceptedNull = true; 2966 if (map.nullKeyEntry != null) { 2967 action.accept(map.nullKeyEntry); 2968 if (map.modCount != expectedModCount) 2969 throw new ConcurrentModificationException(); 2970 return true; 2971 } 2972 } 2973 if (tab.length >= hi && index >= 0) { 2974 while (current != null || index < hi) { 2975 if (current == null) { 2976 current = tab[index++]; 2977 if (current instanceof HashMap.TreeBin) { 2978 current = ((HashMap.TreeBin)current).first; 2979 } 2980 } else { 2981 HashMap.Entry<K,V> e; 2982 if (current instanceof HashMap.Entry) { 2983 e = (Entry<K,V>)current; 2984 } else { 2985 e = (Entry<K,V>)((TreeNode)current).entry; 2986 } 2987 current = e.next; 2988 action.accept(e); 2989 if (map.modCount != expectedModCount) 2990 throw new ConcurrentModificationException(); 2991 return true; 2992 } 2993 } 2994 } 2995 return false; 2996 } 2997 2998 public int characteristics() { 2999 return (fence < 0 || est == map.size ? Spliterator.SIZED : 0) | 3000 Spliterator.DISTINCT; 3001 } 3002 } 3003 }