Java工具类——HashMap源码分析

《Java工具类——HashMap源码分析》
《Java工具类——HashMap源码分析》

   1 /*
   2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
   4  *
   5  *
   6  *
   7  *
   8  *
   9  *
  10  *
  11  *
  12  *
  13  *
  14  *
  15  *
  16  *
  17  *
  18  *
  19  *
  20  *
  21  *
  22  *
  23  *
  24  */
  25 
  26 package java.util;
  27 import java.io.*;
  28 
  29 /**
  30  * Hash table based implementation of the <tt>Map</tt> interface.  This
  31  * implementation provides all of the optional map operations, and permits
  32  * <tt>null</tt> values and the <tt>null</tt> key.  (The <tt>HashMap</tt>
  33  * class is roughly equivalent to <tt>Hashtable</tt>, except that it is
  34  * unsynchronized and permits nulls.)  This class makes no guarantees as to
  35  * the order of the map; in particular, it does not guarantee that the order
  36  * will remain constant over time.
  37  *
  38  * <p>This implementation provides constant-time performance for the basic
  39  * operations (<tt>get</tt> and <tt>put</tt>), assuming the hash function
  40  * disperses the elements properly among the buckets.  Iteration over
  41  * collection views requires time proportional to the "capacity" of the
  42  * <tt>HashMap</tt> instance (the number of buckets) plus its size (the number
  43  * of key-value mappings).  Thus, it's very important not to set the initial
  44  * capacity too high (or the load factor too low) if iteration performance is
  45  * important.
  46  *
  47  * <p>An instance of <tt>HashMap</tt> has two parameters that affect its
  48  * performance: <i>initial capacity</i> and <i>load factor</i>.  The
  49  * <i>capacity</i> is the number of buckets in the hash table, and the initial
  50  * capacity is simply the capacity at the time the hash table is created.  The
  51  * <i>load factor</i> is a measure of how full the hash table is allowed to
  52  * get before its capacity is automatically increased.  When the number of
  53  * entries in the hash table exceeds the product of the load factor and the
  54  * current capacity, the hash table is <i>rehashed</i> (that is, internal data
  55  * structures are rebuilt) so that the hash table has approximately twice the
  56  * number of buckets.
  57  *
  58  * <p>As a general rule, the default load factor (.75) offers a good tradeoff
  59  * between time and space costs.  Higher values decrease the space overhead
  60  * but increase the lookup cost (reflected in most of the operations of the
  61  * <tt>HashMap</tt> class, including <tt>get</tt> and <tt>put</tt>).  The
  62  * expected number of entries in the map and its load factor should be taken
  63  * into account when setting its initial capacity, so as to minimize the
  64  * number of rehash operations.  If the initial capacity is greater
  65  * than the maximum number of entries divided by the load factor, no
  66  * rehash operations will ever occur.
  67  *
  68  * <p>If many mappings are to be stored in a <tt>HashMap</tt> instance,
  69  * creating it with a sufficiently large capacity will allow the mappings to
  70  * be stored more efficiently than letting it perform automatic rehashing as
  71  * needed to grow the table.
  72  *
  73  * <p><strong>Note that this implementation is not synchronized.</strong>
  74  * If multiple threads access a hash map concurrently, and at least one of
  75  * the threads modifies the map structurally, it <i>must</i> be
  76  * synchronized externally.  (A structural modification is any operation
  77  * that adds or deletes one or more mappings; merely changing the value
  78  * associated with a key that an instance already contains is not a
  79  * structural modification.)  This is typically accomplished by
  80  * synchronizing on some object that naturally encapsulates the map.
  81  *
  82  * If no such object exists, the map should be "wrapped" using the
  83  * {@link Collections#synchronizedMap Collections.synchronizedMap}
  84  * method.  This is best done at creation time, to prevent accidental
  85  * unsynchronized access to the map:<pre>
  86  *   Map m = Collections.synchronizedMap(new HashMap(...));</pre>
  87  *
  88  * <p>The iterators returned by all of this class's "collection view methods"
  89  * are <i>fail-fast</i>: if the map is structurally modified at any time after
  90  * the iterator is created, in any way except through the iterator's own
  91  * <tt>remove</tt> method, the iterator will throw a
  92  * {@link ConcurrentModificationException}.  Thus, in the face of concurrent
  93  * modification, the iterator fails quickly and cleanly, rather than risking
  94  * arbitrary, non-deterministic behavior at an undetermined time in the
  95  * future.
  96  *
  97  * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
  98  * as it is, generally speaking, impossible to make any hard guarantees in the
  99  * presence of unsynchronized concurrent modification.  Fail-fast iterators
 100  * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
 101  * Therefore, it would be wrong to write a program that depended on this
 102  * exception for its correctness: <i>the fail-fast behavior of iterators
 103  * should be used only to detect bugs.</i>
 104  *
 105  * <p>This class is a member of the
 106  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
 107  * Java Collections Framework</a>.
 108  *
 109  * @param <K> the type of keys maintained by this map
 110  * @param <V> the type of mapped values
 111  *
 112  * @author  Doug Lea
 113  * @author  Josh Bloch
 114  * @author  Arthur van Hoff
 115  * @author  Neal Gafter
 116  * @see     Object#hashCode()
 117  * @see     Collection
 118  * @see     Map
 119  * @see     TreeMap
 120  * @see     Hashtable
 121  * @since   1.2
 122  */
 123 
 124 public class HashMap<K,V>
 125     extends AbstractMap<K,V>
 126     implements Map<K,V>, Cloneable, Serializable
 127 {
 128 
 129     /**
 130      * The default initial capacity - MUST be a power of two.
 131      */
 132     static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
 133 
 134     /**
 135      * The maximum capacity, used if a higher value is implicitly specified
 136      * by either of the constructors with arguments.
 137      * MUST be a power of two <= 1<<30.
 138      */
 139     static final int MAXIMUM_CAPACITY = 1 << 30;
 140 
 141     /**
 142      * The load factor used when none specified in constructor.
 143      */
 144     static final float DEFAULT_LOAD_FACTOR = 0.75f;
 145 
 146     /**
 147      * An empty table instance to share when the table is not inflated.
 148      */
 149     static final Entry<?,?>[] EMPTY_TABLE = {};
 150 
 151     /**
 152      * The table, resized as necessary. Length MUST Always be a power of two.
 153      */
 154     transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;
 155 
 156     /**
 157      * The number of key-value mappings contained in this map.
 158      */
 159     transient int size;
 160 
 161     /**
 162      * The next size value at which to resize (capacity * load factor).
 163      * @serial
 164      */
 165     // If table == EMPTY_TABLE then this is the initial capacity at which the
 166     // table will be created when inflated.
 167     int threshold;
 168 
 169     /**
 170      * The load factor for the hash table.
 171      *
 172      * @serial
 173      */
 174     final float loadFactor;
 175 
 176     /**
 177      * The number of times this HashMap has been structurally modified
 178      * Structural modifications are those that change the number of mappings in
 179      * the HashMap or otherwise modify its internal structure (e.g.,
 180      * rehash).  This field is used to make iterators on Collection-views of
 181      * the HashMap fail-fast.  (See ConcurrentModificationException).
 182      */
 183     transient int modCount;
 184 
 185     /**
 186      * The default threshold of map capacity above which alternative hashing is
 187      * used for String keys. Alternative hashing reduces the incidence of
 188      * collisions due to weak hash code calculation for String keys.
 189      * <p/>
 190      * This value may be overridden by defining the system property
 191      * {@code jdk.map.althashing.threshold}. A property value of {@code 1}
 192      * forces alternative hashing to be used at all times whereas
 193      * {@code -1} value ensures that alternative hashing is never used.
 194      */
 195     static final int ALTERNATIVE_HASHING_THRESHOLD_DEFAULT = Integer.MAX_VALUE;
 196 
 197     /**
 198      * holds values which can't be initialized until after VM is booted.
 199      */
 200     private static class Holder {
 201 
 202         /**
 203          * Table capacity above which to switch to use alternative hashing.
 204          */
 205         static final int ALTERNATIVE_HASHING_THRESHOLD;
 206 
 207         static {
 208             String altThreshold = java.security.AccessController.doPrivileged(
 209                 new sun.security.action.GetPropertyAction(
 210                     "jdk.map.althashing.threshold"));
 211 
 212             int threshold;
 213             try {
 214                 threshold = (null != altThreshold)
 215                         ? Integer.parseInt(altThreshold)
 216                         : ALTERNATIVE_HASHING_THRESHOLD_DEFAULT;
 217 
 218                 // disable alternative hashing if -1
 219                 if (threshold == -1) {
 220                     threshold = Integer.MAX_VALUE;
 221                 }
 222 
 223                 if (threshold < 0) {
 224                     throw new IllegalArgumentException("value must be positive integer.");
 225                 }
 226             } catch(IllegalArgumentException failed) {
 227                 throw new Error("Illegal value for 'jdk.map.althashing.threshold'", failed);
 228             }
 229 
 230             ALTERNATIVE_HASHING_THRESHOLD = threshold;
 231         }
 232     }
 233 
 234     /**
 235      * A randomizing value associated with this instance that is applied to
 236      * hash code of keys to make hash collisions harder to find. If 0 then
 237      * alternative hashing is disabled.
 238      */
 239     transient int hashSeed = 0;
 240 
 241     /**
 242      * Constructs an empty <tt>HashMap</tt> with the specified initial
 243      * capacity and load factor.
 244      *
 245      * @param  initialCapacity the initial capacity
 246      * @param  loadFactor      the load factor
 247      * @throws IllegalArgumentException if the initial capacity is negative
 248      *         or the load factor is nonpositive
 249      */
 250     public HashMap(int initialCapacity, float loadFactor) {
 251         if (initialCapacity < 0)
 252             throw new IllegalArgumentException("Illegal initial capacity: " +
 253                                                initialCapacity);
 254         if (initialCapacity > MAXIMUM_CAPACITY)
 255             initialCapacity = MAXIMUM_CAPACITY;
 256         if (loadFactor <= 0 || Float.isNaN(loadFactor))
 257             throw new IllegalArgumentException("Illegal load factor: " +
 258                                                loadFactor);
 259 
 260         this.loadFactor = loadFactor;
 261         threshold = initialCapacity;
 262         init();
 263     }
 264 
 265     /**
 266      * Constructs an empty <tt>HashMap</tt> with the specified initial
 267      * capacity and the default load factor (0.75).
 268      *
 269      * @param  initialCapacity the initial capacity.
 270      * @throws IllegalArgumentException if the initial capacity is negative.
 271      */
 272     public HashMap(int initialCapacity) {
 273         this(initialCapacity, DEFAULT_LOAD_FACTOR);
 274     }
 275 
 276     /**
 277      * Constructs an empty <tt>HashMap</tt> with the default initial capacity
 278      * (16) and the default load factor (0.75).
 279      */
 280     public HashMap() {
 281         this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
 282     }
 283 
 284     /**
 285      * Constructs a new <tt>HashMap</tt> with the same mappings as the
 286      * specified <tt>Map</tt>.  The <tt>HashMap</tt> is created with
 287      * default load factor (0.75) and an initial capacity sufficient to
 288      * hold the mappings in the specified <tt>Map</tt>.
 289      *
 290      * @param   m the map whose mappings are to be placed in this map
 291      * @throws  NullPointerException if the specified map is null
 292      */
 293     public HashMap(Map<? extends K, ? extends V> m) {
 294         this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
 295                       DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
 296         inflateTable(threshold);
 297 
 298         putAllForCreate(m);
 299     }
 300 
 301     private static int roundUpToPowerOf2(int number) {
 302         // assert number >= 0 : "number must be non-negative";
 303         int rounded = number >= MAXIMUM_CAPACITY
 304                 ? MAXIMUM_CAPACITY
 305                 : (rounded = Integer.highestOneBit(number)) != 0
 306                     ? (Integer.bitCount(number) > 1) ? rounded << 1 : rounded
 307                     : 1;
 308 
 309         return rounded;
 310     }
 311 
 312     /**
 313      * Inflates the table.
 314      */
 315     private void inflateTable(int toSize) {
 316         // Find a power of 2 >= toSize
 317         int capacity = roundUpToPowerOf2(toSize);
 318 
 319         threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
 320         table = new Entry[capacity];
 321         initHashSeedAsNeeded(capacity);
 322     }
 323 
 324     // internal utilities
 325 
 326     /**
 327      * Initialization hook for subclasses. This method is called
 328      * in all constructors and pseudo-constructors (clone, readObject)
 329      * after HashMap has been initialized but before any entries have
 330      * been inserted.  (In the absence of this method, readObject would
 331      * require explicit knowledge of subclasses.)
 332      */
 333     void init() {
 334     }
 335 
 336     /**
 337      * Initialize the hashing mask value. We defer initialization until we
 338      * really need it.
 339      */
 340     final boolean initHashSeedAsNeeded(int capacity) {
 341         boolean currentAltHashing = hashSeed != 0;
 342         boolean useAltHashing = sun.misc.VM.isBooted() &&
 343                 (capacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD);
 344         boolean switching = currentAltHashing ^ useAltHashing;
 345         if (switching) {
 346             hashSeed = useAltHashing
 347                 ? sun.misc.Hashing.randomHashSeed(this)
 348                 : 0;
 349         }
 350         return switching;
 351     }
 352 
 353     /**
 354      * Retrieve object hash code and applies a supplemental hash function to the
 355      * result hash, which defends against poor quality hash functions.  This is
 356      * critical because HashMap uses power-of-two length hash tables, that
 357      * otherwise encounter collisions for hashCodes that do not differ
 358      * in lower bits. Note: Null keys always map to hash 0, thus index 0.
 359      */
 360     final int hash(Object k) {
 361         int h = hashSeed;
 362         if (0 != h && k instanceof String) {
 363             return sun.misc.Hashing.stringHash32((String) k);
 364         }
 365 
 366         h ^= k.hashCode();
 367 
 368         // This function ensures that hashCodes that differ only by
 369         // constant multiples at each bit position have a bounded
 370         // number of collisions (approximately 8 at default load factor).
 371         h ^= (h >>> 20) ^ (h >>> 12);
 372         return h ^ (h >>> 7) ^ (h >>> 4);
 373     }
 374 
 375     /**
 376      * Returns index for hash code h.
 377      */
 378     static int indexFor(int h, int length) {
 379         // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
 380         return h & (length-1);
 381     }
 382 
 383     /**
 384      * Returns the number of key-value mappings in this map.
 385      *
 386      * @return the number of key-value mappings in this map
 387      */
 388     public int size() {
 389         return size;
 390     }
 391 
 392     /**
 393      * Returns <tt>true</tt> if this map contains no key-value mappings.
 394      *
 395      * @return <tt>true</tt> if this map contains no key-value mappings
 396      */
 397     public boolean isEmpty() {
 398         return size == 0;
 399     }
 400 
 401     /**
 402      * Returns the value to which the specified key is mapped,
 403      * or {@code null} if this map contains no mapping for the key.
 404      *
 405      * <p>More formally, if this map contains a mapping from a key
 406      * {@code k} to a value {@code v} such that {@code (key==null ? k==null :
 407      * key.equals(k))}, then this method returns {@code v}; otherwise
 408      * it returns {@code null}.  (There can be at most one such mapping.)
 409      *
 410      * <p>A return value of {@code null} does not <i>necessarily</i>
 411      * indicate that the map contains no mapping for the key; it's also
 412      * possible that the map explicitly maps the key to {@code null}.
 413      * The {@link #containsKey containsKey} operation may be used to
 414      * distinguish these two cases.
 415      *
 416      * @see #put(Object, Object)
 417      */
 418     public V get(Object key) {
 419         if (key == null)
 420             return getForNullKey();
 421         Entry<K,V> entry = getEntry(key);
 422 
 423         return null == entry ? null : entry.getValue();
 424     }
 425 
 426     /**
 427      * Offloaded version of get() to look up null keys.  Null keys map
 428      * to index 0.  This null case is split out into separate methods
 429      * for the sake of performance in the two most commonly used
 430      * operations (get and put), but incorporated with conditionals in
 431      * others.
 432      */
 433     private V getForNullKey() {
 434         if (size == 0) {
 435             return null;
 436         }
 437         for (Entry<K,V> e = table[0]; e != null; e = e.next) {
 438             if (e.key == null)
 439                 return e.value;
 440         }
 441         return null;
 442     }
 443 
 444     /**
 445      * Returns <tt>true</tt> if this map contains a mapping for the
 446      * specified key.
 447      *
 448      * @param   key   The key whose presence in this map is to be tested
 449      * @return <tt>true</tt> if this map contains a mapping for the specified
 450      * key.
 451      */
 452     public boolean containsKey(Object key) {
 453         return getEntry(key) != null;
 454     }
 455 
 456     /**
 457      * Returns the entry associated with the specified key in the
 458      * HashMap.  Returns null if the HashMap contains no mapping
 459      * for the key.
 460      */
 461     final Entry<K,V> getEntry(Object key) {
 462         if (size == 0) {
 463             return null;
 464         }
 465 
 466         int hash = (key == null) ? 0 : hash(key);
 467         for (Entry<K,V> e = table[indexFor(hash, table.length)];
 468              e != null;
 469              e = e.next) {
 470             Object k;
 471             if (e.hash == hash &&
 472                 ((k = e.key) == key || (key != null && key.equals(k))))
 473                 return e;
 474         }
 475         return null;
 476     }
 477 
 478     /**
 479      * Associates the specified value with the specified key in this map.
 480      * If the map previously contained a mapping for the key, the old
 481      * value is replaced.
 482      *
 483      * @param key key with which the specified value is to be associated
 484      * @param value value to be associated with the specified key
 485      * @return the previous value associated with <tt>key</tt>, or
 486      *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
 487      *         (A <tt>null</tt> return can also indicate that the map
 488      *         previously associated <tt>null</tt> with <tt>key</tt>.)
 489      */
 490     public V put(K key, V value) {
 491         if (table == EMPTY_TABLE) {
 492             inflateTable(threshold);
 493         }
 494         if (key == null)
 495             return putForNullKey(value);
 496         int hash = hash(key);
 497         int i = indexFor(hash, table.length);
 498         for (Entry<K,V> e = table[i]; e != null; e = e.next) {
 499             Object k;
 500             if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
 501                 V oldValue = e.value;
 502                 e.value = value;
 503                 e.recordAccess(this);
 504                 return oldValue;
 505             }
 506         }
 507 
 508         modCount++;
 509         addEntry(hash, key, value, i);
 510         return null;
 511     }
 512 
 513     /**
 514      * Offloaded version of put for null keys
 515      */
 516     private V putForNullKey(V value) {
 517         for (Entry<K,V> e = table[0]; e != null; e = e.next) {
 518             if (e.key == null) {
 519                 V oldValue = e.value;
 520                 e.value = value;
 521                 e.recordAccess(this);
 522                 return oldValue;
 523             }
 524         }
 525         modCount++;
 526         addEntry(0, null, value, 0);
 527         return null;
 528     }
 529 
 530     /**
 531      * This method is used instead of put by constructors and
 532      * pseudoconstructors (clone, readObject).  It does not resize the table,
 533      * check for comodification, etc.  It calls createEntry rather than
 534      * addEntry.
 535      */
 536     private void putForCreate(K key, V value) {
 537         int hash = null == key ? 0 : hash(key);
 538         int i = indexFor(hash, table.length);
 539 
 540         /**
 541          * Look for preexisting entry for key.  This will never happen for
 542          * clone or deserialize.  It will only happen for construction if the
 543          * input Map is a sorted map whose ordering is inconsistent w/ equals.
 544          */
 545         for (Entry<K,V> e = table[i]; e != null; e = e.next) {
 546             Object k;
 547             if (e.hash == hash &&
 548                 ((k = e.key) == key || (key != null && key.equals(k)))) {
 549                 e.value = value;
 550                 return;
 551             }
 552         }
 553 
 554         createEntry(hash, key, value, i);
 555     }
 556 
 557     private void putAllForCreate(Map<? extends K, ? extends V> m) {
 558         for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
 559             putForCreate(e.getKey(), e.getValue());
 560     }
 561 
 562     /**
 563      * Rehashes the contents of this map into a new array with a
 564      * larger capacity.  This method is called automatically when the
 565      * number of keys in this map reaches its threshold.
 566      *
 567      * If current capacity is MAXIMUM_CAPACITY, this method does not
 568      * resize the map, but sets threshold to Integer.MAX_VALUE.
 569      * This has the effect of preventing future calls.
 570      *
 571      * @param newCapacity the new capacity, MUST be a power of two;
 572      *        must be greater than current capacity unless current
 573      *        capacity is MAXIMUM_CAPACITY (in which case value
 574      *        is irrelevant).
 575      */
 576     void resize(int newCapacity) {
 577         Entry[] oldTable = table;
 578         int oldCapacity = oldTable.length;
 579         if (oldCapacity == MAXIMUM_CAPACITY) {
 580             threshold = Integer.MAX_VALUE;
 581             return;
 582         }
 583 
 584         Entry[] newTable = new Entry[newCapacity];
 585         transfer(newTable, initHashSeedAsNeeded(newCapacity));
 586         table = newTable;
 587         threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
 588     }
 589 
 590     /**
 591      * Transfers all entries from current table to newTable.
 592      */
 593     void transfer(Entry[] newTable, boolean rehash) {
 594         int newCapacity = newTable.length;
 595         for (Entry<K,V> e : table) {
 596             while(null != e) {
 597                 Entry<K,V> next = e.next;
 598                 if (rehash) {
 599                     e.hash = null == e.key ? 0 : hash(e.key);
 600                 }
 601                 int i = indexFor(e.hash, newCapacity);
 602                 e.next = newTable[i];
 603                 newTable[i] = e;
 604                 e = next;
 605             }
 606         }
 607     }
 608 
 609     /**
 610      * Copies all of the mappings from the specified map to this map.
 611      * These mappings will replace any mappings that this map had for
 612      * any of the keys currently in the specified map.
 613      *
 614      * @param m mappings to be stored in this map
 615      * @throws NullPointerException if the specified map is null
 616      */
 617     public void putAll(Map<? extends K, ? extends V> m) {
 618         int numKeysToBeAdded = m.size();
 619         if (numKeysToBeAdded == 0)
 620             return;
 621 
 622         if (table == EMPTY_TABLE) {
 623             inflateTable((int) Math.max(numKeysToBeAdded * loadFactor, threshold));
 624         }
 625 
 626         /*
 627          * Expand the map if the map if the number of mappings to be added
 628          * is greater than or equal to threshold.  This is conservative; the
 629          * obvious condition is (m.size() + size) >= threshold, but this
 630          * condition could result in a map with twice the appropriate capacity,
 631          * if the keys to be added overlap with the keys already in this map.
 632          * By using the conservative calculation, we subject ourself
 633          * to at most one extra resize.
 634          */
 635         if (numKeysToBeAdded > threshold) {
 636             int targetCapacity = (int)(numKeysToBeAdded / loadFactor + 1);
 637             if (targetCapacity > MAXIMUM_CAPACITY)
 638                 targetCapacity = MAXIMUM_CAPACITY;
 639             int newCapacity = table.length;
 640             while (newCapacity < targetCapacity)
 641                 newCapacity <<= 1;
 642             if (newCapacity > table.length)
 643                 resize(newCapacity);
 644         }
 645 
 646         for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
 647             put(e.getKey(), e.getValue());
 648     }
 649 
 650     /**
 651      * Removes the mapping for the specified key from this map if present.
 652      *
 653      * @param  key key whose mapping is to be removed from the map
 654      * @return the previous value associated with <tt>key</tt>, or
 655      *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
 656      *         (A <tt>null</tt> return can also indicate that the map
 657      *         previously associated <tt>null</tt> with <tt>key</tt>.)
 658      */
 659     public V remove(Object key) {
 660         Entry<K,V> e = removeEntryForKey(key);
 661         return (e == null ? null : e.value);
 662     }
 663 
 664     /**
 665      * Removes and returns the entry associated with the specified key
 666      * in the HashMap.  Returns null if the HashMap contains no mapping
 667      * for this key.
 668      */
 669     final Entry<K,V> removeEntryForKey(Object key) {
 670         if (size == 0) {
 671             return null;
 672         }
 673         int hash = (key == null) ? 0 : hash(key);
 674         int i = indexFor(hash, table.length);
 675         Entry<K,V> prev = table[i];
 676         Entry<K,V> e = prev;
 677 
 678         while (e != null) {
 679             Entry<K,V> next = e.next;
 680             Object k;
 681             if (e.hash == hash &&
 682                 ((k = e.key) == key || (key != null && key.equals(k)))) {
 683                 modCount++;
 684                 size--;
 685                 if (prev == e)
 686                     table[i] = next;
 687                 else
 688                     prev.next = next;
 689                 e.recordRemoval(this);
 690                 return e;
 691             }
 692             prev = e;
 693             e = next;
 694         }
 695 
 696         return e;
 697     }
 698 
 699     /**
 700      * Special version of remove for EntrySet using {@code Map.Entry.equals()}
 701      * for matching.
 702      */
 703     final Entry<K,V> removeMapping(Object o) {
 704         if (size == 0 || !(o instanceof Map.Entry))
 705             return null;
 706 
 707         Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
 708         Object key = entry.getKey();
 709         int hash = (key == null) ? 0 : hash(key);
 710         int i = indexFor(hash, table.length);
 711         Entry<K,V> prev = table[i];
 712         Entry<K,V> e = prev;
 713 
 714         while (e != null) {
 715             Entry<K,V> next = e.next;
 716             if (e.hash == hash && e.equals(entry)) {
 717                 modCount++;
 718                 size--;
 719                 if (prev == e)
 720                     table[i] = next;
 721                 else
 722                     prev.next = next;
 723                 e.recordRemoval(this);
 724                 return e;
 725             }
 726             prev = e;
 727             e = next;
 728         }
 729 
 730         return e;
 731     }
 732 
 733     /**
 734      * Removes all of the mappings from this map.
 735      * The map will be empty after this call returns.
 736      */
 737     public void clear() {
 738         modCount++;
 739         Arrays.fill(table, null);
 740         size = 0;
 741     }
 742 
 743     /**
 744      * Returns <tt>true</tt> if this map maps one or more keys to the
 745      * specified value.
 746      *
 747      * @param value value whose presence in this map is to be tested
 748      * @return <tt>true</tt> if this map maps one or more keys to the
 749      *         specified value
 750      */
 751     public boolean containsValue(Object value) {
 752         if (value == null)
 753             return containsNullValue();
 754 
 755         Entry[] tab = table;
 756         for (int i = 0; i < tab.length ; i++)
 757             for (Entry e = tab[i] ; e != null ; e = e.next)
 758                 if (value.equals(e.value))
 759                     return true;
 760         return false;
 761     }
 762 
 763     /**
 764      * Special-case code for containsValue with null argument
 765      */
 766     private boolean containsNullValue() {
 767         Entry[] tab = table;
 768         for (int i = 0; i < tab.length ; i++)
 769             for (Entry e = tab[i] ; e != null ; e = e.next)
 770                 if (e.value == null)
 771                     return true;
 772         return false;
 773     }
 774 
 775     /**
 776      * Returns a shallow copy of this <tt>HashMap</tt> instance: the keys and
 777      * values themselves are not cloned.
 778      *
 779      * @return a shallow copy of this map
 780      */
 781     public Object clone() {
 782         HashMap<K,V> result = null;
 783         try {
 784             result = (HashMap<K,V>)super.clone();
 785         } catch (CloneNotSupportedException e) {
 786             // assert false;
 787         }
 788         if (result.table != EMPTY_TABLE) {
 789             result.inflateTable(Math.min(
 790                 (int) Math.min(
 791                     size * Math.min(1 / loadFactor, 4.0f),
 792                     // we have limits...
 793                     HashMap.MAXIMUM_CAPACITY),
 794                table.length));
 795         }
 796         result.entrySet = null;
 797         result.modCount = 0;
 798         result.size = 0;
 799         result.init();
 800         result.putAllForCreate(this);
 801 
 802         return result;
 803     }
 804 
 805     static class Entry<K,V> implements Map.Entry<K,V> {
 806         final K key;
 807         V value;
 808         Entry<K,V> next;
 809         int hash;
 810 
 811         /**
 812          * Creates new entry.
 813          */
 814         Entry(int h, K k, V v, Entry<K,V> n) {
 815             value = v;
 816             next = n;
 817             key = k;
 818             hash = h;
 819         }
 820 
 821         public final K getKey() {
 822             return key;
 823         }
 824 
 825         public final V getValue() {
 826             return value;
 827         }
 828 
 829         public final V setValue(V newValue) {
 830             V oldValue = value;
 831             value = newValue;
 832             return oldValue;
 833         }
 834 
 835         public final boolean equals(Object o) {
 836             if (!(o instanceof Map.Entry))
 837                 return false;
 838             Map.Entry e = (Map.Entry)o;
 839             Object k1 = getKey();
 840             Object k2 = e.getKey();
 841             if (k1 == k2 || (k1 != null && k1.equals(k2))) {
 842                 Object v1 = getValue();
 843                 Object v2 = e.getValue();
 844                 if (v1 == v2 || (v1 != null && v1.equals(v2)))
 845                     return true;
 846             }
 847             return false;
 848         }
 849 
 850         public final int hashCode() {
 851             return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
 852         }
 853 
 854         public final String toString() {
 855             return getKey() + "=" + getValue();
 856         }
 857 
 858         /**
 859          * This method is invoked whenever the value in an entry is
 860          * overwritten by an invocation of put(k,v) for a key k that's already
 861          * in the HashMap.
 862          */
 863         void recordAccess(HashMap<K,V> m) {
 864         }
 865 
 866         /**
 867          * This method is invoked whenever the entry is
 868          * removed from the table.
 869          */
 870         void recordRemoval(HashMap<K,V> m) {
 871         }
 872     }
 873 
 874     /**
 875      * Adds a new entry with the specified key, value and hash code to
 876      * the specified bucket.  It is the responsibility of this
 877      * method to resize the table if appropriate.
 878      *
 879      * Subclass overrides this to alter the behavior of put method.
 880      */
 881     void addEntry(int hash, K key, V value, int bucketIndex) {
 882         if ((size >= threshold) && (null != table[bucketIndex])) {
 883             resize(2 * table.length);
 884             hash = (null != key) ? hash(key) : 0;
 885             bucketIndex = indexFor(hash, table.length);
 886         }
 887 
 888         createEntry(hash, key, value, bucketIndex);
 889     }
 890 
 891     /**
 892      * Like addEntry except that this version is used when creating entries
 893      * as part of Map construction or "pseudo-construction" (cloning,
 894      * deserialization).  This version needn't worry about resizing the table.
 895      *
 896      * Subclass overrides this to alter the behavior of HashMap(Map),
 897      * clone, and readObject.
 898      */
 899     void createEntry(int hash, K key, V value, int bucketIndex) {
 900         Entry<K,V> e = table[bucketIndex];
 901         table[bucketIndex] = new Entry<>(hash, key, value, e);
 902         size++;
 903     }
 904 
 905     private abstract class HashIterator<E> implements Iterator<E> {
 906         Entry<K,V> next;        // next entry to return
 907         int expectedModCount;   // For fast-fail
 908         int index;              // current slot
 909         Entry<K,V> current;     // current entry
 910 
 911         HashIterator() {
 912             expectedModCount = modCount;
 913             if (size > 0) { // advance to first entry
 914                 Entry[] t = table;
 915                 while (index < t.length && (next = t[index++]) == null)
 916                     ;
 917             }
 918         }
 919 
 920         public final boolean hasNext() {
 921             return next != null;
 922         }
 923 
 924         final Entry<K,V> nextEntry() {
 925             if (modCount != expectedModCount)
 926                 throw new ConcurrentModificationException();
 927             Entry<K,V> e = next;
 928             if (e == null)
 929                 throw new NoSuchElementException();
 930 
 931             if ((next = e.next) == null) {
 932                 Entry[] t = table;
 933                 while (index < t.length && (next = t[index++]) == null)
 934                     ;
 935             }
 936             current = e;
 937             return e;
 938         }
 939 
 940         public void remove() {
 941             if (current == null)
 942                 throw new IllegalStateException();
 943             if (modCount != expectedModCount)
 944                 throw new ConcurrentModificationException();
 945             Object k = current.key;
 946             current = null;
 947             HashMap.this.removeEntryForKey(k);
 948             expectedModCount = modCount;
 949         }
 950     }
 951 
 952     private final class ValueIterator extends HashIterator<V> {
 953         public V next() {
 954             return nextEntry().value;
 955         }
 956     }
 957 
 958     private final class KeyIterator extends HashIterator<K> {
 959         public K next() {
 960             return nextEntry().getKey();
 961         }
 962     }
 963 
 964     private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
 965         public Map.Entry<K,V> next() {
 966             return nextEntry();
 967         }
 968     }
 969 
 970     // Subclass overrides these to alter behavior of views' iterator() method
 971     Iterator<K> newKeyIterator()   {
 972         return new KeyIterator();
 973     }
 974     Iterator<V> newValueIterator()   {
 975         return new ValueIterator();
 976     }
 977     Iterator<Map.Entry<K,V>> newEntryIterator()   {
 978         return new EntryIterator();
 979     }
 980 
 981 
 982     // Views
 983 
 984     private transient Set<Map.Entry<K,V>> entrySet = null;
 985 
 986     /**
 987      * Returns a {@link Set} view of the keys contained in this map.
 988      * The set is backed by the map, so changes to the map are
 989      * reflected in the set, and vice-versa.  If the map is modified
 990      * while an iteration over the set is in progress (except through
 991      * the iterator's own <tt>remove</tt> operation), the results of
 992      * the iteration are undefined.  The set supports element removal,
 993      * which removes the corresponding mapping from the map, via the
 994      * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
 995      * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
 996      * operations.  It does not support the <tt>add</tt> or <tt>addAll</tt>
 997      * operations.
 998      */
 999     public Set<K> keySet() {
1000         Set<K> ks = keySet;
1001         return (ks != null ? ks : (keySet = new KeySet()));
1002     }
1003 
1004     private final class KeySet extends AbstractSet<K> {
1005         public Iterator<K> iterator() {
1006             return newKeyIterator();
1007         }
1008         public int size() {
1009             return size;
1010         }
1011         public boolean contains(Object o) {
1012             return containsKey(o);
1013         }
1014         public boolean remove(Object o) {
1015             return HashMap.this.removeEntryForKey(o) != null;
1016         }
1017         public void clear() {
1018             HashMap.this.clear();
1019         }
1020     }
1021 
1022     /**
1023      * Returns a {@link Collection} view of the values contained in this map.
1024      * The collection is backed by the map, so changes to the map are
1025      * reflected in the collection, and vice-versa.  If the map is
1026      * modified while an iteration over the collection is in progress
1027      * (except through the iterator's own <tt>remove</tt> operation),
1028      * the results of the iteration are undefined.  The collection
1029      * supports element removal, which removes the corresponding
1030      * mapping from the map, via the <tt>Iterator.remove</tt>,
1031      * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
1032      * <tt>retainAll</tt> and <tt>clear</tt> operations.  It does not
1033      * support the <tt>add</tt> or <tt>addAll</tt> operations.
1034      */
1035     public Collection<V> values() {
1036         Collection<V> vs = values;
1037         return (vs != null ? vs : (values = new Values()));
1038     }
1039 
1040     private final class Values extends AbstractCollection<V> {
1041         public Iterator<V> iterator() {
1042             return newValueIterator();
1043         }
1044         public int size() {
1045             return size;
1046         }
1047         public boolean contains(Object o) {
1048             return containsValue(o);
1049         }
1050         public void clear() {
1051             HashMap.this.clear();
1052         }
1053     }
1054 
1055     /**
1056      * Returns a {@link Set} view of the mappings contained in this map.
1057      * The set is backed by the map, so changes to the map are
1058      * reflected in the set, and vice-versa.  If the map is modified
1059      * while an iteration over the set is in progress (except through
1060      * the iterator's own <tt>remove</tt> operation, or through the
1061      * <tt>setValue</tt> operation on a map entry returned by the
1062      * iterator) the results of the iteration are undefined.  The set
1063      * supports element removal, which removes the corresponding
1064      * mapping from the map, via the <tt>Iterator.remove</tt>,
1065      * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
1066      * <tt>clear</tt> operations.  It does not support the
1067      * <tt>add</tt> or <tt>addAll</tt> operations.
1068      *
1069      * @return a set view of the mappings contained in this map
1070      */
1071     public Set<Map.Entry<K,V>> entrySet() {
1072         return entrySet0();
1073     }
1074 
1075     private Set<Map.Entry<K,V>> entrySet0() {
1076         Set<Map.Entry<K,V>> es = entrySet;
1077         return es != null ? es : (entrySet = new EntrySet());
1078     }
1079 
1080     private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
1081         public Iterator<Map.Entry<K,V>> iterator() {
1082             return newEntryIterator();
1083         }
1084         public boolean contains(Object o) {
1085             if (!(o instanceof Map.Entry))
1086                 return false;
1087             Map.Entry<K,V> e = (Map.Entry<K,V>) o;
1088             Entry<K,V> candidate = getEntry(e.getKey());
1089             return candidate != null && candidate.equals(e);
1090         }
1091         public boolean remove(Object o) {
1092             return removeMapping(o) != null;
1093         }
1094         public int size() {
1095             return size;
1096         }
1097         public void clear() {
1098             HashMap.this.clear();
1099         }
1100     }
1101 
1102     /**
1103      * Save the state of the <tt>HashMap</tt> instance to a stream (i.e.,
1104      * serialize it).
1105      *
1106      * @serialData The <i>capacity</i> of the HashMap (the length of the
1107      *             bucket array) is emitted (int), followed by the
1108      *             <i>size</i> (an int, the number of key-value
1109      *             mappings), followed by the key (Object) and value (Object)
1110      *             for each key-value mapping.  The key-value mappings are
1111      *             emitted in no particular order.
1112      */
1113     private void writeObject(java.io.ObjectOutputStream s)
1114         throws IOException
1115     {
1116         // Write out the threshold, loadfactor, and any hidden stuff
1117         s.defaultWriteObject();
1118 
1119         // Write out number of buckets
1120         if (table==EMPTY_TABLE) {
1121             s.writeInt(roundUpToPowerOf2(threshold));
1122         } else {
1123            s.writeInt(table.length);
1124         }
1125 
1126         // Write out size (number of Mappings)
1127         s.writeInt(size);
1128 
1129         // Write out keys and values (alternating)
1130         if (size > 0) {
1131             for(Map.Entry<K,V> e : entrySet0()) {
1132                 s.writeObject(e.getKey());
1133                 s.writeObject(e.getValue());
1134             }
1135         }
1136     }
1137 
1138     private static final long serialVersionUID = 362498820763181265L;
1139 
1140     /**
1141      * Reconstitute the {@code HashMap} instance from a stream (i.e.,
1142      * deserialize it).
1143      */
1144     private void readObject(java.io.ObjectInputStream s)
1145          throws IOException, ClassNotFoundException
1146     {
1147         // Read in the threshold (ignored), loadfactor, and any hidden stuff
1148         s.defaultReadObject();
1149         if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
1150             throw new InvalidObjectException("Illegal load factor: " +
1151                                                loadFactor);
1152         }
1153 
1154         // set other fields that need values
1155         table = (Entry<K,V>[]) EMPTY_TABLE;
1156 
1157         // Read in number of buckets
1158         s.readInt(); // ignored.
1159 
1160         // Read number of mappings
1161         int mappings = s.readInt();
1162         if (mappings < 0)
1163             throw new InvalidObjectException("Illegal mappings count: " +
1164                                                mappings);
1165 
1166         // capacity chosen by number of mappings and desired load (if >= 0.25)
1167         int capacity = (int) Math.min(
1168                     mappings * Math.min(1 / loadFactor, 4.0f),
1169                     // we have limits...
1170                     HashMap.MAXIMUM_CAPACITY);
1171 
1172         // allocate the bucket array;
1173         if (mappings > 0) {
1174             inflateTable(capacity);
1175         } else {
1176             threshold = capacity;
1177         }
1178 
1179         init();  // Give subclass a chance to do its thing.
1180 
1181         // Read the keys and values, and put the mappings in the HashMap
1182         for (int i = 0; i < mappings; i++) {
1183             K key = (K) s.readObject();
1184             V value = (V) s.readObject();
1185             putForCreate(key, value);
1186         }
1187     }
1188 
1189     // These methods are used when serializing HashSets
1190     int   capacity()     { return table.length; }
1191     float loadFactor()   { return loadFactor;   }
1192 }

HashMap

   1 /*
   2  * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
   3  * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
   4  *
   5  *
   6  *
   7  *
   8  *
   9  *
  10  *
  11  *
  12  *
  13  *
  14  *
  15  *
  16  *
  17  *
  18  *
  19  *
  20  *
  21  *
  22  *
  23  *
  24  */
  25 
  26 package java.util;
  27 import java.io.*;
  28 
  29 /**
  30  * Hash table based implementation of the <tt>Map</tt> interface.  This
  31  * implementation provides all of the optional map operations, and permits
  32  * <tt>null</tt> values and the <tt>null</tt> key.  (The <tt>HashMap</tt>
  33  * class is roughly(粗糙地;概略地) equivalent(相等的,相当的) to <tt>Hashtable</tt>, except that it is
  34  * unsynchronized(非同步的) and permits nulls.)  This class makes no guarantees as to
  35  * the order of the map; in particular(尤其,特别), it does not guarantee(保证) that the order
  36  * will remain constant over time.
  37  *
  38  * <p>This implementation provides constant-time performance for the basic
  39  * operations (<tt>get</tt> and <tt>put</tt>), assuming the hash function
  40  * disperses(散开,驱散) the elements properly among the buckets(桶).  Iteration over
  41  * collection views requires time proportional to the "capacity" of the
  42  * <tt>HashMap</tt> instance (the number of buckets) plus its size (the number
  43  * of key-value mappings).  Thus, it's very important not to set the initial
  44  * capacity too high (or the load factor too low) if iteration performance is
  45  * important.
  46  *
  47  * <p>An instance(例子,实例) of <tt>HashMap</tt> has two parameters that affect its
  48  * performance: <i>initial capacity</i> and <i>load factor</i>.  The
  49  * <i>capacity</i> is the number of buckets in the hash table, and the initial
  50  * capacity is simply the capacity at the time the hash table is created.  The
  51  * <i>load factor</i> is a measure of how full the hash table is allowed to
  52  * get before its capacity is automatically increased.  When the number of
  53  * entries in the hash table exceeds(超过;超越) the product of the load factor and the
  54  * current capacity, the hash table is <i>rehashed</i> (that is, internal data
  55  * structures are rebuilt) so that the hash table has approximately(近似地,大约) twice the
  56  * number of buckets.
  57  *
  58  * <p>As a general rule, the default load factor (.75) offers a good tradeoff(权衡,折中)
  59  * between time and space costs.  Higher values decrease the space overhead
  60  * but increase the lookup cost (reflected in most of the operations of the
  61  * <tt>HashMap</tt> class, including <tt>get</tt> and <tt>put</tt>).  The
  62  * expected number of entries in the map and its load factor should be taken
  63  * into account when setting its initial capacity, so as to minimize the
  64  * number of rehash operations.  If the initial capacity is greater
  65  * than the maximum number of entries divided by the load factor, no
  66  * rehash operations will ever occur.
  67  *
  68  * <p>If many mappings are to be stored in a <tt>HashMap</tt> instance,
  69  * creating it with a sufficiently large capacity will allow the mappings to
  70  * be stored more efficiently than letting it perform automatic rehashing as
  71  * needed to grow the table.
  72  *
  73  * <p><strong>Note that this implementation is not synchronized.</strong>   74  * If multiple threads access a hash map concurrently, and at least one of
  75  * the threads modifies the map structurally, it <i>must</i> be
  76  * synchronized externally.  (A structural modification is any operation
  77  * that adds or deletes one or more mappings; merely changing the value
  78  * associated with a key that an instance already contains is not a
  79  * structural modification.)  This is typically accomplished by
  80  * synchronizing on some object that naturally encapsulates(总结;扼要概括) the map.
  81  *
  82  * If no such object exists, the map should be "wrapped" using the
  83  * {@link Collections#synchronizedMap Collections.synchronizedMap}
  84  * method.  This is best done at creation time, to prevent accidental
  85  * unsynchronized access to the map:<pre>
  86  *   Map m = Collections.synchronizedMap(new HashMap(...));</pre>
  87  *
  88  * <p>The iterators returned by all of this class's "collection view methods"
  89  * are <i>fail-fast</i>: if the map is structurally modified at any time after
  90  * the iterator is created, in any way except through the iterator's own
  91  * <tt>remove</tt> method, the iterator will throw a
  92  * {@link ConcurrentModificationException}.  Thus, in the face of concurrent
  93  * modification, the iterator fails quickly and cleanly, rather than risking
  94  * arbitrary, non-deterministic behavior at an undetermined time in the
  95  * future.
  96  *
  97  * <p>Note that the fail-fast behavior of an iterator cannot be guaranteed
  98  * as it is, generally speaking, impossible to make any hard guarantees in the
  99  * presence of unsynchronized concurrent modification.  Fail-fast iterators
 100  * throw <tt>ConcurrentModificationException</tt> on a best-effort basis.
 101  * Therefore, it would be wrong to write a program that depended on this
 102  * exception for its correctness: <i>the fail-fast behavior of iterators
 103  * should be used only to detect bugs.</i>
 104  *
 105  * <p>This class is a member of the
 106  * <a href="{@docRoot}/../technotes/guides/collections/index.html">
 107  * Java Collections Framework</a>.
 108  *
 109  * @param <K> the type of keys maintained by this map
 110  * @param <V> the type of mapped values
 111  *
 112  * @author  Doug Lea
 113  * @author  Josh Bloch
 114  * @author  Arthur van Hoff
 115  * @author  Neal Gafter
 116  * @see     Object#hashCode()
 117  * @see     Collection
 118  * @see     Map
 119  * @see     TreeMap
 120  * @see     Hashtable
 121  * @since   1.2
 122  */
 123 
 124 public class HashMap<K,V>
 125     extends AbstractMap<K,V>
 126     implements Map<K,V>, Cloneable, Serializable
 127 {
 128 
 129     /**
 130      * The default initial capacity - MUST be a power of two.
 131      */
 132     static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
 133 
 134     /**
 135      * The maximum capacity, used if a higher value is implicitly specified
 136      * by either of the constructors with arguments.
 137      * MUST be a power of two <= 1<<30.
 138      */
 139     static final int MAXIMUM_CAPACITY = 1 << 30;
 140 
 141     /**
 142      * The load factor used when none specified in constructor.
 143      */
 144     static final float DEFAULT_LOAD_FACTOR = 0.75f;
 145 
 146     /**
 147      * An empty table instance to share when the table is not inflated.
 148      */
 149     static final Entry<?,?>[] EMPTY_TABLE = {};
 150 
 151     /**
 152      * The table, resized as necessary. Length MUST Always be a power of two.
 153      */
 154     transient Entry<K,V>[] table = (Entry<K,V>[]) EMPTY_TABLE;
 155 
 156     /**
 157      * The number of key-value mappings contained in this map.
 158      */
 159     transient int size;
 160 
 161     /**
 162      * The next size value at which to resize (capacity * load factor).
 163      * @serial
 164      */
 165     // If table == EMPTY_TABLE then this is the initial capacity at which the
 166     // table will be created when inflated.
 167     int threshold;
 168 
 169     /**
 170      * The load factor for the hash table.
 171      *
 172      * @serial
 173      */
 174     final float loadFactor;
 175 
 176     /**
 177      * The number of times this HashMap has been structurally modified
 178      * Structural modifications are those that change the number of mappings in
 179      * the HashMap or otherwise modify its internal structure (e.g.,
 180      * rehash).  This field is used to make iterators on Collection-views of
 181      * the HashMap fail-fast.  (See ConcurrentModificationException).
 182      */
 183     transient int modCount;
 184 
 185     /**
 186      * The default threshold of map capacity above which alternative hashing is
 187      * used for String keys. Alternative hashing reduces the incidence of
 188      * collisions due to weak hash code calculation for String keys.
 189      * <p/>
 190      * This value may be overridden by defining the system property
 191      * {@code jdk.map.althashing.threshold}. A property value of {@code 1}
 192      * forces alternative hashing to be used at all times whereas
 193      * {@code -1} value ensures that alternative hashing is never used.
 194      */
 195     static final int ALTERNATIVE_HASHING_THRESHOLD_DEFAULT = Integer.MAX_VALUE;
 196 
 197     /**
 198      * holds values which can't be initialized until after VM is booted.
 199      */
 200     private static class Holder {
 201 
 202         /**
 203          * Table capacity above which to switch to use alternative hashing.
 204          */
 205         static final int ALTERNATIVE_HASHING_THRESHOLD;
 206 
 207         static {
 208             String altThreshold = java.security.AccessController.doPrivileged(
 209                 new sun.security.action.GetPropertyAction(
 210                     "jdk.map.althashing.threshold"));
 211 
 212             int threshold;
 213             try {
 214                 threshold = (null != altThreshold)
 215                         ? Integer.parseInt(altThreshold)
 216                         : ALTERNATIVE_HASHING_THRESHOLD_DEFAULT;
 217 
 218                 // disable alternative hashing if -1
 219                 if (threshold == -1) {
 220                     threshold = Integer.MAX_VALUE;
 221                 }
 222 
 223                 if (threshold < 0) {
 224                     throw new IllegalArgumentException("value must be positive integer.");
 225                 }
 226             } catch(IllegalArgumentException failed) {
 227                 throw new Error("Illegal value for 'jdk.map.althashing.threshold'", failed);
 228             }
 229 
 230             ALTERNATIVE_HASHING_THRESHOLD = threshold;
 231         }
 232     }
 233 
 234     /**
 235      * A randomizing value associated with this instance that is applied to
 236      * hash code of keys to make hash collisions harder to find. If 0 then
 237      * alternative hashing is disabled.
 238      */
 239     transient int hashSeed = 0;
 240 
 241     /**
 242      * Constructs an empty <tt>HashMap</tt> with the specified initial
 243      * capacity and load factor.
 244      *
 245      * @param  initialCapacity the initial capacity
 246      * @param  loadFactor      the load factor
 247      * @throws IllegalArgumentException if the initial capacity is negative
 248      *         or the load factor is nonpositive
 249      */
 250     public HashMap(int initialCapacity, float loadFactor) {
 251         if (initialCapacity < 0)
 252             throw new IllegalArgumentException("Illegal initial capacity: " +
 253                                                initialCapacity);
 254         if (initialCapacity > MAXIMUM_CAPACITY)
 255             initialCapacity = MAXIMUM_CAPACITY;
 256         if (loadFactor <= 0 || Float.isNaN(loadFactor))
 257             throw new IllegalArgumentException("Illegal load factor: " +
 258                                                loadFactor);
 259 
 260         this.loadFactor = loadFactor;
 261         threshold = initialCapacity;
 262         init();
 263     }
 264 
 265     /**
 266      * Constructs an empty <tt>HashMap</tt> with the specified initial
 267      * capacity and the default load factor (0.75).
 268      *
 269      * @param  initialCapacity the initial capacity.
 270      * @throws IllegalArgumentException if the initial capacity is negative.
 271      */
 272     public HashMap(int initialCapacity) {
 273         this(initialCapacity, DEFAULT_LOAD_FACTOR);
 274     }
 275 
 276     /**
 277      * Constructs an empty <tt>HashMap</tt> with the default initial capacity
 278      * (16) and the default load factor (0.75).
 279      */
 280     public HashMap() {
 281         this(DEFAULT_INITIAL_CAPACITY, DEFAULT_LOAD_FACTOR);
 282     }
 283 
 284     /**
 285      * Constructs a new <tt>HashMap</tt> with the same mappings as the
 286      * specified <tt>Map</tt>.  The <tt>HashMap</tt> is created with
 287      * default load factor (0.75) and an initial capacity sufficient to
 288      * hold the mappings in the specified <tt>Map</tt>.
 289      *
 290      * @param   m the map whose mappings are to be placed in this map
 291      * @throws  NullPointerException if the specified map is null
 292      */
 293     public HashMap(Map<? extends K, ? extends V> m) {
 294         this(Math.max((int) (m.size() / DEFAULT_LOAD_FACTOR) + 1,
 295                       DEFAULT_INITIAL_CAPACITY), DEFAULT_LOAD_FACTOR);
 296         inflateTable(threshold);
 297 
 298         putAllForCreate(m);
 299     }
 300 
 301     private static int roundUpToPowerOf2(int number) {
 302         // assert number >= 0 : "number must be non-negative";
 303         int rounded = number >= MAXIMUM_CAPACITY
 304                 ? MAXIMUM_CAPACITY
 305                 : (rounded = Integer.highestOneBit(number)) != 0
 306                     ? (Integer.bitCount(number) > 1) ? rounded << 1 : rounded
 307                     : 1;
 308 
 309         return rounded;
 310     }
 311 
 312     /**
 313      * Inflates the table.
 314      */
 315     private void inflateTable(int toSize) {
 316         // Find a power of 2 >= toSize
 317         int capacity = roundUpToPowerOf2(toSize);
 318 
 319         threshold = (int) Math.min(capacity * loadFactor, MAXIMUM_CAPACITY + 1);
 320         table = new Entry[capacity];
 321         initHashSeedAsNeeded(capacity);
 322     }
 323 
 324     // internal utilities
 325 
 326     /**
 327      * Initialization hook for subclasses. This method is called
 328      * in all constructors and pseudo-constructors (clone, readObject)
 329      * after HashMap has been initialized but before any entries have
 330      * been inserted.  (In the absence of this method, readObject would
 331      * require explicit knowledge of subclasses.)
 332      */
 333     void init() {
 334     }
 335 
 336     /**
 337      * Initialize the hashing mask value. We defer initialization until we
 338      * really need it.
 339      */
 340     final boolean initHashSeedAsNeeded(int capacity) {
 341         boolean currentAltHashing = hashSeed != 0;
 342         boolean useAltHashing = sun.misc.VM.isBooted() &&
 343                 (capacity >= Holder.ALTERNATIVE_HASHING_THRESHOLD);
 344         boolean switching = currentAltHashing ^ useAltHashing;
 345         if (switching) {
 346             hashSeed = useAltHashing
 347                 ? sun.misc.Hashing.randomHashSeed(this)
 348                 : 0;
 349         }
 350         return switching;
 351     }
 352 
 353     /**
 354      * Retrieve object hash code and applies a supplemental hash function to the
 355      * result hash, which defends against poor quality hash functions.  This is
 356      * critical because HashMap uses power-of-two length hash tables, that
 357      * otherwise encounter collisions for hashCodes that do not differ
 358      * in lower bits. Note: Null keys always map to hash 0, thus index 0.
 359      */
 360     final int hash(Object k) {
 361         int h = hashSeed;
 362         if (0 != h && k instanceof String) {
 363             return sun.misc.Hashing.stringHash32((String) k);
 364         }
 365 
 366         h ^= k.hashCode();
 367 
 368         // This function ensures that hashCodes that differ only by
 369         // constant multiples at each bit position have a bounded
 370         // number of collisions (approximately 8 at default load factor).
 371         h ^= (h >>> 20) ^ (h >>> 12);
 372         return h ^ (h >>> 7) ^ (h >>> 4);
 373     }
 374 
 375     /**
 376      * Returns index for hash code h.
 377      */
 378     static int indexFor(int h, int length) {
 379         // assert Integer.bitCount(length) == 1 : "length must be a non-zero power of 2";
 380         return h & (length-1);
 381     }
 382 
 383     /**
 384      * Returns the number of key-value mappings in this map.
 385      *
 386      * @return the number of key-value mappings in this map
 387      */
 388     public int size() {
 389         return size;
 390     }
 391 
 392     /**
 393      * Returns <tt>true</tt> if this map contains no key-value mappings.
 394      *
 395      * @return <tt>true</tt> if this map contains no key-value mappings
 396      */
 397     public boolean isEmpty() {
 398         return size == 0;
 399     }
 400 
 401     /**
 402      * Returns the value to which the specified key is mapped,
 403      * or {@code null} if this map contains no mapping for the key.
 404      *
 405      * <p>More formally, if this map contains a mapping from a key
 406      * {@code k} to a value {@code v} such that {@code (key==null ? k==null :
 407      * key.equals(k))}, then this method returns {@code v}; otherwise
 408      * it returns {@code null}.  (There can be at most one such mapping.)
 409      *
 410      * <p>A return value of {@code null} does not <i>necessarily</i>
 411      * indicate that the map contains no mapping for the key; it's also
 412      * possible that the map explicitly maps the key to {@code null}.
 413      * The {@link #containsKey containsKey} operation may be used to
 414      * distinguish these two cases.
 415      *
 416      * @see #put(Object, Object)
 417      */
 418     public V get(Object key) {
 419         if (key == null)
 420             return getForNullKey();
 421         Entry<K,V> entry = getEntry(key);
 422 
 423         return null == entry ? null : entry.getValue();
 424     }
 425 
 426     /**
 427      * Offloaded version of get() to look up null keys.  Null keys map
 428      * to index 0.  This null case is split out into separate methods
 429      * for the sake of performance in the two most commonly used
 430      * operations (get and put), but incorporated with conditionals in
 431      * others.
 432      */
 433     private V getForNullKey() {
 434         if (size == 0) {
 435             return null;
 436         }
 437         for (Entry<K,V> e = table[0]; e != null; e = e.next) {
 438             if (e.key == null)
 439                 return e.value;
 440         }
 441         return null;
 442     }
 443 
 444     /**
 445      * Returns <tt>true</tt> if this map contains a mapping for the
 446      * specified key.
 447      *
 448      * @param   key   The key whose presence in this map is to be tested
 449      * @return <tt>true</tt> if this map contains a mapping for the specified
 450      * key.
 451      */
 452     public boolean containsKey(Object key) {
 453         return getEntry(key) != null;
 454     }
 455 
 456     /**
 457      * Returns the entry associated with the specified key in the
 458      * HashMap.  Returns null if the HashMap contains no mapping
 459      * for the key.
 460      */
 461     final Entry<K,V> getEntry(Object key) {
 462         if (size == 0) {
 463             return null;
 464         }
 465 
 466         int hash = (key == null) ? 0 : hash(key);
 467         for (Entry<K,V> e = table[indexFor(hash, table.length)];
 468              e != null;
 469              e = e.next) {
 470             Object k;
 471             if (e.hash == hash &&
 472                 ((k = e.key) == key || (key != null && key.equals(k))))
 473                 return e;
 474         }
 475         return null;
 476     }
 477 
 478     /**
 479      * Associates the specified value with the specified key in this map.
 480      * If the map previously contained a mapping for the key, the old
 481      * value is replaced.
 482      *
 483      * @param key key with which the specified value is to be associated
 484      * @param value value to be associated with the specified key
 485      * @return the previous value associated with <tt>key</tt>, or
 486      *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
 487      *         (A <tt>null</tt> return can also indicate that the map
 488      *         previously associated <tt>null</tt> with <tt>key</tt>.)
 489      */
 490     public V put(K key, V value) {
 491         if (table == EMPTY_TABLE) {
 492             inflateTable(threshold);
 493         }
 494         if (key == null)
 495             return putForNullKey(value);
 496         int hash = hash(key);
 497         int i = indexFor(hash, table.length);
 498         for (Entry<K,V> e = table[i]; e != null; e = e.next) {
 499             Object k;
 500             if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
 501                 V oldValue = e.value;
 502                 e.value = value;
 503                 e.recordAccess(this);
 504                 return oldValue;
 505             }
 506         }
 507 
 508         modCount++;
 509         addEntry(hash, key, value, i);
 510         return null;
 511     }
 512 
 513     /**
 514      * Offloaded version of put for null keys
 515      */
 516     private V putForNullKey(V value) {
 517         for (Entry<K,V> e = table[0]; e != null; e = e.next) {
 518             if (e.key == null) {
 519                 V oldValue = e.value;
 520                 e.value = value;
 521                 e.recordAccess(this);
 522                 return oldValue;
 523             }
 524         }
 525         modCount++;
 526         addEntry(0, null, value, 0);
 527         return null;
 528     }
 529 
 530     /**
 531      * This method is used instead of put by constructors and
 532      * pseudoconstructors (clone, readObject).  It does not resize the table,
 533      * check for comodification, etc.  It calls createEntry rather than
 534      * addEntry.
 535      */
 536     private void putForCreate(K key, V value) {
 537         int hash = null == key ? 0 : hash(key);
 538         int i = indexFor(hash, table.length);
 539 
 540         /**
 541          * Look for preexisting entry for key.  This will never happen for
 542          * clone or deserialize.  It will only happen for construction if the
 543          * input Map is a sorted map whose ordering is inconsistent w/ equals.
 544          */
 545         for (Entry<K,V> e = table[i]; e != null; e = e.next) {
 546             Object k;
 547             if (e.hash == hash &&
 548                 ((k = e.key) == key || (key != null && key.equals(k)))) {
 549                 e.value = value;
 550                 return;
 551             }
 552         }
 553 
 554         createEntry(hash, key, value, i);
 555     }
 556 
 557     private void putAllForCreate(Map<? extends K, ? extends V> m) {
 558         for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
 559             putForCreate(e.getKey(), e.getValue());
 560     }
 561 
 562     /**
 563      * Rehashes the contents of this map into a new array with a
 564      * larger capacity.  This method is called automatically when the
 565      * number of keys in this map reaches its threshold.
 566      *
 567      * If current capacity is MAXIMUM_CAPACITY, this method does not
 568      * resize the map, but sets threshold to Integer.MAX_VALUE.
 569      * This has the effect of preventing future calls.
 570      *
 571      * @param newCapacity the new capacity, MUST be a power of two;
 572      *        must be greater than current capacity unless current
 573      *        capacity is MAXIMUM_CAPACITY (in which case value
 574      *        is irrelevant).
 575      */
 576     void resize(int newCapacity) {
 577         Entry[] oldTable = table;
 578         int oldCapacity = oldTable.length;
 579         if (oldCapacity == MAXIMUM_CAPACITY) {
 580             threshold = Integer.MAX_VALUE;
 581             return;
 582         }
 583 
 584         Entry[] newTable = new Entry[newCapacity];
 585         transfer(newTable, initHashSeedAsNeeded(newCapacity));
 586         table = newTable;
 587         threshold = (int)Math.min(newCapacity * loadFactor, MAXIMUM_CAPACITY + 1);
 588     }
 589 
 590     /**
 591      * Transfers all entries from current table to newTable.
 592      */
 593     void transfer(Entry[] newTable, boolean rehash) {
 594         int newCapacity = newTable.length;
 595         for (Entry<K,V> e : table) {
 596             while(null != e) {
 597                 Entry<K,V> next = e.next;
 598                 if (rehash) {
 599                     e.hash = null == e.key ? 0 : hash(e.key);
 600                 }
 601                 int i = indexFor(e.hash, newCapacity);
 602                 e.next = newTable[i];
 603                 newTable[i] = e;
 604                 e = next;
 605             }
 606         }
 607     }
 608 
 609     /**
 610      * Copies all of the mappings from the specified map to this map.
 611      * These mappings will replace any mappings that this map had for
 612      * any of the keys currently in the specified map.
 613      *
 614      * @param m mappings to be stored in this map
 615      * @throws NullPointerException if the specified map is null
 616      */
 617     public void putAll(Map<? extends K, ? extends V> m) {
 618         int numKeysToBeAdded = m.size();
 619         if (numKeysToBeAdded == 0)
 620             return;
 621 
 622         if (table == EMPTY_TABLE) {
 623             inflateTable((int) Math.max(numKeysToBeAdded * loadFactor, threshold));
 624         }
 625 
 626         /*
 627          * Expand the map if the map if the number of mappings to be added
 628          * is greater than or equal to threshold.  This is conservative; the
 629          * obvious condition is (m.size() + size) >= threshold, but this
 630          * condition could result in a map with twice the appropriate capacity,
 631          * if the keys to be added overlap with the keys already in this map.
 632          * By using the conservative calculation, we subject ourself
 633          * to at most one extra resize.
 634          */
 635         if (numKeysToBeAdded > threshold) {
 636             int targetCapacity = (int)(numKeysToBeAdded / loadFactor + 1);
 637             if (targetCapacity > MAXIMUM_CAPACITY)
 638                 targetCapacity = MAXIMUM_CAPACITY;
 639             int newCapacity = table.length;
 640             while (newCapacity < targetCapacity)
 641                 newCapacity <<= 1;
 642             if (newCapacity > table.length)
 643                 resize(newCapacity);
 644         }
 645 
 646         for (Map.Entry<? extends K, ? extends V> e : m.entrySet())
 647             put(e.getKey(), e.getValue());
 648     }
 649 
 650     /**
 651      * Removes the mapping for the specified key from this map if present.
 652      *
 653      * @param  key key whose mapping is to be removed from the map
 654      * @return the previous value associated with <tt>key</tt>, or
 655      *         <tt>null</tt> if there was no mapping for <tt>key</tt>.
 656      *         (A <tt>null</tt> return can also indicate that the map
 657      *         previously associated <tt>null</tt> with <tt>key</tt>.)
 658      */
 659     public V remove(Object key) {
 660         Entry<K,V> e = removeEntryForKey(key);
 661         return (e == null ? null : e.value);
 662     }
 663 
 664     /**
 665      * Removes and returns the entry associated with the specified key
 666      * in the HashMap.  Returns null if the HashMap contains no mapping
 667      * for this key.
 668      */
 669     final Entry<K,V> removeEntryForKey(Object key) {
 670         if (size == 0) {
 671             return null;
 672         }
 673         int hash = (key == null) ? 0 : hash(key);
 674         int i = indexFor(hash, table.length);
 675         Entry<K,V> prev = table[i];
 676         Entry<K,V> e = prev;
 677 
 678         while (e != null) {
 679             Entry<K,V> next = e.next;
 680             Object k;
 681             if (e.hash == hash &&
 682                 ((k = e.key) == key || (key != null && key.equals(k)))) {
 683                 modCount++;
 684                 size--;
 685                 if (prev == e)
 686                     table[i] = next;
 687                 else
 688                     prev.next = next;
 689                 e.recordRemoval(this);
 690                 return e;
 691             }
 692             prev = e;
 693             e = next;
 694         }
 695 
 696         return e;
 697     }
 698 
 699     /**
 700      * Special version of remove for EntrySet using {@code Map.Entry.equals()}
 701      * for matching.
 702      */
 703     final Entry<K,V> removeMapping(Object o) {
 704         if (size == 0 || !(o instanceof Map.Entry))
 705             return null;
 706 
 707         Map.Entry<K,V> entry = (Map.Entry<K,V>) o;
 708         Object key = entry.getKey();
 709         int hash = (key == null) ? 0 : hash(key);
 710         int i = indexFor(hash, table.length);
 711         Entry<K,V> prev = table[i];
 712         Entry<K,V> e = prev;
 713 
 714         while (e != null) {
 715             Entry<K,V> next = e.next;
 716             if (e.hash == hash && e.equals(entry)) {
 717                 modCount++;
 718                 size--;
 719                 if (prev == e)
 720                     table[i] = next;
 721                 else
 722                     prev.next = next;
 723                 e.recordRemoval(this);
 724                 return e;
 725             }
 726             prev = e;
 727             e = next;
 728         }
 729 
 730         return e;
 731     }
 732 
 733     /**
 734      * Removes all of the mappings from this map.
 735      * The map will be empty after this call returns.
 736      */
 737     public void clear() {
 738         modCount++;
 739         Arrays.fill(table, null);
 740         size = 0;
 741     }
 742 
 743     /**
 744      * Returns <tt>true</tt> if this map maps one or more keys to the
 745      * specified value.
 746      *
 747      * @param value value whose presence in this map is to be tested
 748      * @return <tt>true</tt> if this map maps one or more keys to the
 749      *         specified value
 750      */
 751     public boolean containsValue(Object value) {
 752         if (value == null)
 753             return containsNullValue();
 754 
 755         Entry[] tab = table;
 756         for (int i = 0; i < tab.length ; i++)
 757             for (Entry e = tab[i] ; e != null ; e = e.next)
 758                 if (value.equals(e.value))
 759                     return true;
 760         return false;
 761     }
 762 
 763     /**
 764      * Special-case code for containsValue with null argument
 765      */
 766     private boolean containsNullValue() {
 767         Entry[] tab = table;
 768         for (int i = 0; i < tab.length ; i++)
 769             for (Entry e = tab[i] ; e != null ; e = e.next)
 770                 if (e.value == null)
 771                     return true;
 772         return false;
 773     }
 774 
 775     /**
 776      * Returns a shallow copy of this <tt>HashMap</tt> instance: the keys and
 777      * values themselves are not cloned.
 778      *
 779      * @return a shallow copy of this map
 780      */
 781     public Object clone() {
 782         HashMap<K,V> result = null;
 783         try {
 784             result = (HashMap<K,V>)super.clone();
 785         } catch (CloneNotSupportedException e) {
 786             // assert false;
 787         }
 788         if (result.table != EMPTY_TABLE) {
 789             result.inflateTable(Math.min(
 790                 (int) Math.min(
 791                     size * Math.min(1 / loadFactor, 4.0f),
 792                     // we have limits...
 793                     HashMap.MAXIMUM_CAPACITY),
 794                table.length));
 795         }
 796         result.entrySet = null;
 797         result.modCount = 0;
 798         result.size = 0;
 799         result.init();
 800         result.putAllForCreate(this);
 801 
 802         return result;
 803     }
 804 
 805     static class Entry<K,V> implements Map.Entry<K,V> {
 806         final K key;
 807         V value;
 808         Entry<K,V> next;
 809         int hash;
 810 
 811         /**
 812          * Creates new entry.
 813          */
 814         Entry(int h, K k, V v, Entry<K,V> n) {
 815             value = v;
 816             next = n;
 817             key = k;
 818             hash = h;
 819         }
 820 
 821         public final K getKey() {
 822             return key;
 823         }
 824 
 825         public final V getValue() {
 826             return value;
 827         }
 828 
 829         public final V setValue(V newValue) {
 830             V oldValue = value;
 831             value = newValue;
 832             return oldValue;
 833         }
 834 
 835         public final boolean equals(Object o) {
 836             if (!(o instanceof Map.Entry))
 837                 return false;
 838             Map.Entry e = (Map.Entry)o;
 839             Object k1 = getKey();
 840             Object k2 = e.getKey();
 841             if (k1 == k2 || (k1 != null && k1.equals(k2))) {
 842                 Object v1 = getValue();
 843                 Object v2 = e.getValue();
 844                 if (v1 == v2 || (v1 != null && v1.equals(v2)))
 845                     return true;
 846             }
 847             return false;
 848         }
 849 
 850         public final int hashCode() {
 851             return Objects.hashCode(getKey()) ^ Objects.hashCode(getValue());
 852         }
 853 
 854         public final String toString() {
 855             return getKey() + "=" + getValue();
 856         }
 857 
 858         /**
 859          * This method is invoked whenever the value in an entry is
 860          * overwritten by an invocation of put(k,v) for a key k that's already
 861          * in the HashMap.
 862          */
 863         void recordAccess(HashMap<K,V> m) {
 864         }
 865 
 866         /**
 867          * This method is invoked whenever the entry is
 868          * removed from the table.
 869          */
 870         void recordRemoval(HashMap<K,V> m) {
 871         }
 872     }
 873 
 874     /**
 875      * Adds a new entry with the specified key, value and hash code to
 876      * the specified bucket.  It is the responsibility of this
 877      * method to resize the table if appropriate.
 878      *
 879      * Subclass overrides this to alter the behavior of put method.
 880      */
 881     void addEntry(int hash, K key, V value, int bucketIndex) {
 882         if ((size >= threshold) && (null != table[bucketIndex])) {
 883             resize(2 * table.length);
 884             hash = (null != key) ? hash(key) : 0;
 885             bucketIndex = indexFor(hash, table.length);
 886         }
 887 
 888         createEntry(hash, key, value, bucketIndex);
 889     }
 890 
 891     /**
 892      * Like addEntry except that this version is used when creating entries
 893      * as part of Map construction or "pseudo-construction" (cloning,
 894      * deserialization).  This version needn't worry about resizing the table.
 895      *
 896      * Subclass overrides this to alter the behavior of HashMap(Map),
 897      * clone, and readObject.
 898      */
 899     void createEntry(int hash, K key, V value, int bucketIndex) {
 900         Entry<K,V> e = table[bucketIndex];
 901         table[bucketIndex] = new Entry<>(hash, key, value, e);
 902         size++;
 903     }
 904 
 905     private abstract class HashIterator<E> implements Iterator<E> {
 906         Entry<K,V> next;        // next entry to return
 907         int expectedModCount;   // For fast-fail
 908         int index;              // current slot
 909         Entry<K,V> current;     // current entry
 910 
 911         HashIterator() {
 912             expectedModCount = modCount;
 913             if (size > 0) { // advance to first entry
 914                 Entry[] t = table;
 915                 while (index < t.length && (next = t[index++]) == null)
 916                     ;
 917             }
 918         }
 919 
 920         public final boolean hasNext() {
 921             return next != null;
 922         }
 923 
 924         final Entry<K,V> nextEntry() {
 925             if (modCount != expectedModCount)
 926                 throw new ConcurrentModificationException();
 927             Entry<K,V> e = next;
 928             if (e == null)
 929                 throw new NoSuchElementException();
 930 
 931             if ((next = e.next) == null) {
 932                 Entry[] t = table;
 933                 while (index < t.length && (next = t[index++]) == null)
 934                     ;
 935             }
 936             current = e;
 937             return e;
 938         }
 939 
 940         public void remove() {
 941             if (current == null)
 942                 throw new IllegalStateException();
 943             if (modCount != expectedModCount)
 944                 throw new ConcurrentModificationException();
 945             Object k = current.key;
 946             current = null;
 947             HashMap.this.removeEntryForKey(k);
 948             expectedModCount = modCount;
 949         }
 950     }
 951 
 952     private final class ValueIterator extends HashIterator<V> {
 953         public V next() {
 954             return nextEntry().value;
 955         }
 956     }
 957 
 958     private final class KeyIterator extends HashIterator<K> {
 959         public K next() {
 960             return nextEntry().getKey();
 961         }
 962     }
 963 
 964     private final class EntryIterator extends HashIterator<Map.Entry<K,V>> {
 965         public Map.Entry<K,V> next() {
 966             return nextEntry();
 967         }
 968     }
 969 
 970     // Subclass overrides these to alter behavior of views' iterator() method
 971     Iterator<K> newKeyIterator()   {
 972         return new KeyIterator();
 973     }
 974     Iterator<V> newValueIterator()   {
 975         return new ValueIterator();
 976     }
 977     Iterator<Map.Entry<K,V>> newEntryIterator()   {
 978         return new EntryIterator();
 979     }
 980 
 981 
 982     // Views
 983 
 984     private transient Set<Map.Entry<K,V>> entrySet = null;
 985 
 986     /**
 987      * Returns a {@link Set} view of the keys contained in this map.
 988      * The set is backed by the map, so changes to the map are
 989      * reflected in the set, and vice-versa.  If the map is modified
 990      * while an iteration over the set is in progress (except through
 991      * the iterator's own <tt>remove</tt> operation), the results of
 992      * the iteration are undefined.  The set supports element removal,
 993      * which removes the corresponding mapping from the map, via the
 994      * <tt>Iterator.remove</tt>, <tt>Set.remove</tt>,
 995      * <tt>removeAll</tt>, <tt>retainAll</tt>, and <tt>clear</tt>
 996      * operations.  It does not support the <tt>add</tt> or <tt>addAll</tt>
 997      * operations.
 998      */
 999     public Set<K> keySet() {
1000         Set<K> ks = keySet;
1001         return (ks != null ? ks : (keySet = new KeySet()));
1002     }
1003 
1004     private final class KeySet extends AbstractSet<K> {
1005         public Iterator<K> iterator() {
1006             return newKeyIterator();
1007         }
1008         public int size() {
1009             return size;
1010         }
1011         public boolean contains(Object o) {
1012             return containsKey(o);
1013         }
1014         public boolean remove(Object o) {
1015             return HashMap.this.removeEntryForKey(o) != null;
1016         }
1017         public void clear() {
1018             HashMap.this.clear();
1019         }
1020     }
1021 
1022     /**
1023      * Returns a {@link Collection} view of the values contained in this map.
1024      * The collection is backed by the map, so changes to the map are
1025      * reflected in the collection, and vice-versa.  If the map is
1026      * modified while an iteration over the collection is in progress
1027      * (except through the iterator's own <tt>remove</tt> operation),
1028      * the results of the iteration are undefined.  The collection
1029      * supports element removal, which removes the corresponding
1030      * mapping from the map, via the <tt>Iterator.remove</tt>,
1031      * <tt>Collection.remove</tt>, <tt>removeAll</tt>,
1032      * <tt>retainAll</tt> and <tt>clear</tt> operations.  It does not
1033      * support the <tt>add</tt> or <tt>addAll</tt> operations.
1034      */
1035     public Collection<V> values() {
1036         Collection<V> vs = values;
1037         return (vs != null ? vs : (values = new Values()));
1038     }
1039 
1040     private final class Values extends AbstractCollection<V> {
1041         public Iterator<V> iterator() {
1042             return newValueIterator();
1043         }
1044         public int size() {
1045             return size;
1046         }
1047         public boolean contains(Object o) {
1048             return containsValue(o);
1049         }
1050         public void clear() {
1051             HashMap.this.clear();
1052         }
1053     }
1054 
1055     /**
1056      * Returns a {@link Set} view of the mappings contained in this map.
1057      * The set is backed by the map, so changes to the map are
1058      * reflected in the set, and vice-versa.  If the map is modified
1059      * while an iteration over the set is in progress (except through
1060      * the iterator's own <tt>remove</tt> operation, or through the
1061      * <tt>setValue</tt> operation on a map entry returned by the
1062      * iterator) the results of the iteration are undefined.  The set
1063      * supports element removal, which removes the corresponding
1064      * mapping from the map, via the <tt>Iterator.remove</tt>,
1065      * <tt>Set.remove</tt>, <tt>removeAll</tt>, <tt>retainAll</tt> and
1066      * <tt>clear</tt> operations.  It does not support the
1067      * <tt>add</tt> or <tt>addAll</tt> operations.
1068      *
1069      * @return a set view of the mappings contained in this map
1070      */
1071     public Set<Map.Entry<K,V>> entrySet() {
1072         return entrySet0();
1073     }
1074 
1075     private Set<Map.Entry<K,V>> entrySet0() {
1076         Set<Map.Entry<K,V>> es = entrySet;
1077         return es != null ? es : (entrySet = new EntrySet());
1078     }
1079 
1080     private final class EntrySet extends AbstractSet<Map.Entry<K,V>> {
1081         public Iterator<Map.Entry<K,V>> iterator() {
1082             return newEntryIterator();
1083         }
1084         public boolean contains(Object o) {
1085             if (!(o instanceof Map.Entry))
1086                 return false;
1087             Map.Entry<K,V> e = (Map.Entry<K,V>) o;
1088             Entry<K,V> candidate = getEntry(e.getKey());
1089             return candidate != null && candidate.equals(e);
1090         }
1091         public boolean remove(Object o) {
1092             return removeMapping(o) != null;
1093         }
1094         public int size() {
1095             return size;
1096         }
1097         public void clear() {
1098             HashMap.this.clear();
1099         }
1100     }
1101 
1102     /**
1103      * Save the state of the <tt>HashMap</tt> instance to a stream (i.e.,
1104      * serialize it).
1105      *
1106      * @serialData The <i>capacity</i> of the HashMap (the length of the
1107      *             bucket array) is emitted (int), followed by the
1108      *             <i>size</i> (an int, the number of key-value
1109      *             mappings), followed by the key (Object) and value (Object)
1110      *             for each key-value mapping.  The key-value mappings are
1111      *             emitted in no particular order.
1112      */
1113     private void writeObject(java.io.ObjectOutputStream s)
1114         throws IOException
1115     {
1116         // Write out the threshold, loadfactor, and any hidden stuff
1117         s.defaultWriteObject();
1118 
1119         // Write out number of buckets
1120         if (table==EMPTY_TABLE) {
1121             s.writeInt(roundUpToPowerOf2(threshold));
1122         } else {
1123            s.writeInt(table.length);
1124         }
1125 
1126         // Write out size (number of Mappings)
1127         s.writeInt(size);
1128 
1129         // Write out keys and values (alternating)
1130         if (size > 0) {
1131             for(Map.Entry<K,V> e : entrySet0()) {
1132                 s.writeObject(e.getKey());
1133                 s.writeObject(e.getValue());
1134             }
1135         }
1136     }
1137 
1138     private static final long serialVersionUID = 362498820763181265L;
1139 
1140     /**
1141      * Reconstitute the {@code HashMap} instance from a stream (i.e.,
1142      * deserialize it).
1143      */
1144     private void readObject(java.io.ObjectInputStream s)
1145          throws IOException, ClassNotFoundException
1146     {
1147         // Read in the threshold (ignored), loadfactor, and any hidden stuff
1148         s.defaultReadObject();
1149         if (loadFactor <= 0 || Float.isNaN(loadFactor)) {
1150             throw new InvalidObjectException("Illegal load factor: " +
1151                                                loadFactor);
1152         }
1153 
1154         // set other fields that need values
1155         table = (Entry<K,V>[]) EMPTY_TABLE;
1156 
1157         // Read in number of buckets
1158         s.readInt(); // ignored.
1159 
1160         // Read number of mappings
1161         int mappings = s.readInt();
1162         if (mappings < 0)
1163             throw new InvalidObjectException("Illegal mappings count: " +
1164                                                mappings);
1165 
1166         // capacity chosen by number of mappings and desired load (if >= 0.25)
1167         int capacity = (int) Math.min(
1168                     mappings * Math.min(1 / loadFactor, 4.0f),
1169                     // we have limits...
1170                     HashMap.MAXIMUM_CAPACITY);
1171 
1172         // allocate the bucket array;
1173         if (mappings > 0) {
1174             inflateTable(capacity);
1175         } else {
1176             threshold = capacity;
1177         }
1178 
1179         init();  // Give subclass a chance to do its thing.
1180 
1181         // Read the keys and values, and put the mappings in the HashMap
1182         for (int i = 0; i < mappings; i++) {
1183             K key = (K) s.readObject();
1184             V value = (V) s.readObject();
1185             putForCreate(key, value);
1186         }
1187     }
1188 
1189     // These methods are used when serializing HashSets
1190     int   capacity()     { return table.length; }
1191     float loadFactor()   { return loadFactor;   }
1192 }

 

    原文作者:LoveYaner
    原文地址: https://www.cnblogs.com/LideAiYaner-1wn/p/5752295.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞