1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.util; 19 20 import java.io.IOException; 21 import java.io.InvalidObjectException; 22 import java.io.ObjectInputStream; 23 import java.io.ObjectOutputStream; 24 import java.io.ObjectStreamField; 25 import java.io.Serializable; 26 import libcore.util.Objects; 27 28 /** 29 * HashMap is an implementation of {@link Map}. All optional operations are supported. 30 * 31 * <p>All elements are permitted as keys or values, including null. 32 * 33 * <p>Note that the iteration order for HashMap is non-deterministic. If you want 34 * deterministic iteration, use {@link LinkedHashMap}. 35 * 36 * <p>Note: the implementation of {@code HashMap} is not synchronized. 37 * If one thread of several threads accessing an instance modifies the map 38 * structurally, access to the map needs to be synchronized. A structural 39 * modification is an operation that adds or removes an entry. Changes in 40 * the value of an entry are not structural changes. 41 * 42 * <p>The {@code Iterator} created by calling the {@code iterator} method 43 * may throw a {@code ConcurrentModificationException} if the map is structurally 44 * changed while an iterator is used to iterate over the elements. Only the 45 * {@code remove} method that is provided by the iterator allows for removal of 46 * elements during iteration. It is not possible to guarantee that this 47 * mechanism works in all cases of unsynchronized concurrent modification. It 48 * should only be used for debugging purposes. 49 * 50 * @param <K> the type of keys maintained by this map 51 * @param <V> the type of mapped values 52 */ 53 public class HashMap<K, V> extends AbstractMap<K, V> implements Cloneable, Serializable { 54 /** 55 * Min capacity (other than zero) for a HashMap. Must be a power of two 56 * greater than 1 (and less than 1 << 30). 57 */ 58 private static final int MINIMUM_CAPACITY = 4; 59 60 /** 61 * Max capacity for a HashMap. Must be a power of two >= MINIMUM_CAPACITY. 62 */ 63 private static final int MAXIMUM_CAPACITY = 1 << 30; 64 65 /** 66 * An empty table shared by all zero-capacity maps (typically from default 67 * constructor). It is never written to, and replaced on first put. Its size 68 * is set to half the minimum, so that the first resize will create a 69 * minimum-sized table. 70 */ 71 private static final Entry[] EMPTY_TABLE 72 = new HashMapEntry[MINIMUM_CAPACITY >>> 1]; 73 74 /** 75 * The default load factor. Note that this implementation ignores the 76 * load factor, but cannot do away with it entirely because it's 77 * mentioned in the API. 78 * 79 * <p>Note that this constant has no impact on the behavior of the program, 80 * but it is emitted as part of the serialized form. The load factor of 81 * .75 is hardwired into the program, which uses cheap shifts in place of 82 * expensive division. 83 */ 84 static final float DEFAULT_LOAD_FACTOR = .75F; 85 86 /** 87 * The hash table. If this hash map contains a mapping for null, it is 88 * not represented this hash table. 89 */ 90 transient HashMapEntry<K, V>[] table; 91 92 /** 93 * The entry representing the null key, or null if there's no such mapping. 94 */ 95 transient HashMapEntry<K, V> entryForNullKey; 96 97 /** 98 * The number of mappings in this hash map. 99 */ 100 transient int size; 101 102 /** 103 * Incremented by "structural modifications" to allow (best effort) 104 * detection of concurrent modification. 105 */ 106 transient int modCount; 107 108 /** 109 * The table is rehashed when its size exceeds this threshold. 110 * The value of this field is generally .75 * capacity, except when 111 * the capacity is zero, as described in the EMPTY_TABLE declaration 112 * above. 113 */ 114 private transient int threshold; 115 116 // Views - lazily initialized 117 private transient Set<K> keySet; 118 private transient Set<Entry<K, V>> entrySet; 119 private transient Collection<V> values; 120 121 /** 122 * Constructs a new empty {@code HashMap} instance. 123 */ 124 @SuppressWarnings("unchecked") 125 public HashMap() { 126 table = (HashMapEntry<K, V>[]) EMPTY_TABLE; 127 threshold = -1; // Forces first put invocation to replace EMPTY_TABLE 128 } 129 130 /** 131 * Constructs a new {@code HashMap} instance with the specified capacity. 132 * 133 * @param capacity 134 * the initial capacity of this hash map. 135 * @throws IllegalArgumentException 136 * when the capacity is less than zero. 137 */ 138 public HashMap(int capacity) { 139 if (capacity < 0) { 140 throw new IllegalArgumentException("Capacity: " + capacity); 141 } 142 143 if (capacity == 0) { 144 @SuppressWarnings("unchecked") 145 HashMapEntry<K, V>[] tab = (HashMapEntry<K, V>[]) EMPTY_TABLE; 146 table = tab; 147 threshold = -1; // Forces first put() to replace EMPTY_TABLE 148 return; 149 } 150 151 if (capacity < MINIMUM_CAPACITY) { 152 capacity = MINIMUM_CAPACITY; 153 } else if (capacity > MAXIMUM_CAPACITY) { 154 capacity = MAXIMUM_CAPACITY; 155 } else { 156 capacity = Collections.roundUpToPowerOfTwo(capacity); 157 } 158 makeTable(capacity); 159 } 160 161 /** 162 * Constructs a new {@code HashMap} instance with the specified capacity and 163 * load factor. 164 * 165 * @param capacity 166 * the initial capacity of this hash map. 167 * @param loadFactor 168 * the initial load factor. 169 * @throws IllegalArgumentException 170 * when the capacity is less than zero or the load factor is 171 * less or equal to zero or NaN. 172 */ 173 public HashMap(int capacity, float loadFactor) { 174 this(capacity); 175 176 if (loadFactor <= 0 || Float.isNaN(loadFactor)) { 177 throw new IllegalArgumentException("Load factor: " + loadFactor); 178 } 179 180 /* 181 * Note that this implementation ignores loadFactor; it always uses 182 * a load factor of 3/4. This simplifies the code and generally 183 * improves performance. 184 */ 185 } 186 187 /** 188 * Constructs a new {@code HashMap} instance containing the mappings from 189 * the specified map. 190 * 191 * @param map 192 * the mappings to add. 193 */ 194 public HashMap(Map<? extends K, ? extends V> map) { 195 this(capacityForInitSize(map.size())); 196 constructorPutAll(map); 197 } 198 199 /** 200 * Inserts all of the elements of map into this HashMap in a manner 201 * suitable for use by constructors and pseudo-constructors (i.e., clone, 202 * readObject). Also used by LinkedHashMap. 203 */ 204 final void constructorPutAll(Map<? extends K, ? extends V> map) { 205 if (table == EMPTY_TABLE) { 206 doubleCapacity(); // Don't do unchecked puts to a shared table. 207 } 208 for (Entry<? extends K, ? extends V> e : map.entrySet()) { 209 constructorPut(e.getKey(), e.getValue()); 210 } 211 } 212 213 /** 214 * Returns an appropriate capacity for the specified initial size. Does 215 * not round the result up to a power of two; the caller must do this! 216 * The returned value will be between 0 and MAXIMUM_CAPACITY (inclusive). 217 */ 218 static int capacityForInitSize(int size) { 219 int result = (size >> 1) + size; // Multiply by 3/2 to allow for growth 220 221 // boolean expr is equivalent to result >= 0 && result<MAXIMUM_CAPACITY 222 return (result & ~(MAXIMUM_CAPACITY-1))==0 ? result : MAXIMUM_CAPACITY; 223 } 224 225 /** 226 * Returns a shallow copy of this map. 227 * 228 * @return a shallow copy of this map. 229 */ 230 @SuppressWarnings("unchecked") 231 @Override public Object clone() { 232 /* 233 * This could be made more efficient. It unnecessarily hashes all of 234 * the elements in the map. 235 */ 236 HashMap<K, V> result; 237 try { 238 result = (HashMap<K, V>) super.clone(); 239 } catch (CloneNotSupportedException e) { 240 throw new AssertionError(e); 241 } 242 243 // Restore clone to empty state, retaining our capacity and threshold 244 result.makeTable(table.length); 245 result.entryForNullKey = null; 246 result.size = 0; 247 result.keySet = null; 248 result.entrySet = null; 249 result.values = null; 250 251 result.init(); // Give subclass a chance to initialize itself 252 result.constructorPutAll(this); // Calls method overridden in subclass!! 253 return result; 254 } 255 256 /** 257 * This method is called from the pseudo-constructors (clone and readObject) 258 * prior to invoking constructorPut/constructorPutAll, which invoke the 259 * overridden constructorNewEntry method. Normally it is a VERY bad idea to 260 * invoke an overridden method from a pseudo-constructor (Effective Java 261 * Item 17). In this case it is unavoidable, and the init method provides a 262 * workaround. 263 */ 264 void init() { } 265 266 /** 267 * Returns whether this map is empty. 268 * 269 * @return {@code true} if this map has no elements, {@code false} 270 * otherwise. 271 * @see #size() 272 */ 273 @Override public boolean isEmpty() { 274 return size == 0; 275 } 276 277 /** 278 * Returns the number of elements in this map. 279 * 280 * @return the number of elements in this map. 281 */ 282 @Override public int size() { 283 return size; 284 } 285 286 /** 287 * Returns the value of the mapping with the specified key. 288 * 289 * @param key 290 * the key. 291 * @return the value of the mapping with the specified key, or {@code null} 292 * if no mapping for the specified key is found. 293 */ 294 public V get(Object key) { 295 if (key == null) { 296 HashMapEntry<K, V> e = entryForNullKey; 297 return e == null ? null : e.value; 298 } 299 300 // Doug Lea's supplemental secondaryHash function (inlined). 301 // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590). 302 int hash = key.hashCode(); 303 hash ^= (hash >>> 20) ^ (hash >>> 12); 304 hash ^= (hash >>> 7) ^ (hash >>> 4); 305 306 HashMapEntry<K, V>[] tab = table; 307 for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)]; 308 e != null; e = e.next) { 309 K eKey = e.key; 310 if (eKey == key || (e.hash == hash && key.equals(eKey))) { 311 return e.value; 312 } 313 } 314 return null; 315 } 316 317 /** 318 * Returns whether this map contains the specified key. 319 * 320 * @param key 321 * the key to search for. 322 * @return {@code true} if this map contains the specified key, 323 * {@code false} otherwise. 324 */ 325 @Override public boolean containsKey(Object key) { 326 if (key == null) { 327 return entryForNullKey != null; 328 } 329 330 // Doug Lea's supplemental secondaryHash function (inlined). 331 // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590). 332 int hash = key.hashCode(); 333 hash ^= (hash >>> 20) ^ (hash >>> 12); 334 hash ^= (hash >>> 7) ^ (hash >>> 4); 335 336 HashMapEntry<K, V>[] tab = table; 337 for (HashMapEntry<K, V> e = tab[hash & (tab.length - 1)]; 338 e != null; e = e.next) { 339 K eKey = e.key; 340 if (eKey == key || (e.hash == hash && key.equals(eKey))) { 341 return true; 342 } 343 } 344 return false; 345 } 346 347 // Doug Lea's supplemental secondaryHash function (non-inlined). 348 // Replace with Collections.secondaryHash when the VM is fast enough (http://b/8290590). 349 static int secondaryHash(Object key) { 350 int hash = key.hashCode(); 351 hash ^= (hash >>> 20) ^ (hash >>> 12); 352 hash ^= (hash >>> 7) ^ (hash >>> 4); 353 return hash; 354 } 355 356 /** 357 * Returns whether this map contains the specified value. 358 * 359 * @param value 360 * the value to search for. 361 * @return {@code true} if this map contains the specified value, 362 * {@code false} otherwise. 363 */ 364 @Override public boolean containsValue(Object value) { 365 HashMapEntry[] tab = table; 366 int len = tab.length; 367 if (value == null) { 368 for (int i = 0; i < len; i++) { 369 for (HashMapEntry e = tab[i]; e != null; e = e.next) { 370 if (e.value == null) { 371 return true; 372 } 373 } 374 } 375 return entryForNullKey != null && entryForNullKey.value == null; 376 } 377 378 // value is non-null 379 for (int i = 0; i < len; i++) { 380 for (HashMapEntry e = tab[i]; e != null; e = e.next) { 381 if (value.equals(e.value)) { 382 return true; 383 } 384 } 385 } 386 return entryForNullKey != null && value.equals(entryForNullKey.value); 387 } 388 389 /** 390 * Maps the specified key to the specified value. 391 * 392 * @param key 393 * the key. 394 * @param value 395 * the value. 396 * @return the value of any previous mapping with the specified key or 397 * {@code null} if there was no such mapping. 398 */ 399 @Override public V put(K key, V value) { 400 if (key == null) { 401 return putValueForNullKey(value); 402 } 403 404 int hash = secondaryHash(key); 405 HashMapEntry<K, V>[] tab = table; 406 int index = hash & (tab.length - 1); 407 for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) { 408 if (e.hash == hash && key.equals(e.key)) { 409 preModify(e); 410 V oldValue = e.value; 411 e.value = value; 412 return oldValue; 413 } 414 } 415 416 // No entry for (non-null) key is present; create one 417 modCount++; 418 if (size++ > threshold) { 419 tab = doubleCapacity(); 420 index = hash & (tab.length - 1); 421 } 422 addNewEntry(key, value, hash, index); 423 return null; 424 } 425 426 private V putValueForNullKey(V value) { 427 HashMapEntry<K, V> entry = entryForNullKey; 428 if (entry == null) { 429 addNewEntryForNullKey(value); 430 size++; 431 modCount++; 432 return null; 433 } else { 434 preModify(entry); 435 V oldValue = entry.value; 436 entry.value = value; 437 return oldValue; 438 } 439 } 440 441 /** 442 * Give LinkedHashMap a chance to take action when we modify an existing 443 * entry. 444 * 445 * @param e the entry we're about to modify. 446 */ 447 void preModify(HashMapEntry<K, V> e) { } 448 449 /** 450 * This method is just like put, except that it doesn't do things that 451 * are inappropriate or unnecessary for constructors and pseudo-constructors 452 * (i.e., clone, readObject). In particular, this method does not check to 453 * ensure that capacity is sufficient, and does not increment modCount. 454 */ 455 private void constructorPut(K key, V value) { 456 if (key == null) { 457 HashMapEntry<K, V> entry = entryForNullKey; 458 if (entry == null) { 459 entryForNullKey = constructorNewEntry(null, value, 0, null); 460 size++; 461 } else { 462 entry.value = value; 463 } 464 return; 465 } 466 467 int hash = secondaryHash(key); 468 HashMapEntry<K, V>[] tab = table; 469 int index = hash & (tab.length - 1); 470 HashMapEntry<K, V> first = tab[index]; 471 for (HashMapEntry<K, V> e = first; e != null; e = e.next) { 472 if (e.hash == hash && key.equals(e.key)) { 473 e.value = value; 474 return; 475 } 476 } 477 478 // No entry for (non-null) key is present; create one 479 tab[index] = constructorNewEntry(key, value, hash, first); 480 size++; 481 } 482 483 /** 484 * Creates a new entry for the given key, value, hash, and index and 485 * inserts it into the hash table. This method is called by put 486 * (and indirectly, putAll), and overridden by LinkedHashMap. The hash 487 * must incorporate the secondary hash function. 488 */ 489 void addNewEntry(K key, V value, int hash, int index) { 490 table[index] = new HashMapEntry<K, V>(key, value, hash, table[index]); 491 } 492 493 /** 494 * Creates a new entry for the null key, and the given value and 495 * inserts it into the hash table. This method is called by put 496 * (and indirectly, putAll), and overridden by LinkedHashMap. 497 */ 498 void addNewEntryForNullKey(V value) { 499 entryForNullKey = new HashMapEntry<K, V>(null, value, 0, null); 500 } 501 502 /** 503 * Like newEntry, but does not perform any activity that would be 504 * unnecessary or inappropriate for constructors. In this class, the 505 * two methods behave identically; in LinkedHashMap, they differ. 506 */ 507 HashMapEntry<K, V> constructorNewEntry( 508 K key, V value, int hash, HashMapEntry<K, V> first) { 509 return new HashMapEntry<K, V>(key, value, hash, first); 510 } 511 512 /** 513 * Copies all the mappings in the specified map to this map. These mappings 514 * will replace all mappings that this map had for any of the keys currently 515 * in the given map. 516 * 517 * @param map 518 * the map to copy mappings from. 519 */ 520 @Override public void putAll(Map<? extends K, ? extends V> map) { 521 ensureCapacity(map.size()); 522 super.putAll(map); 523 } 524 525 /** 526 * Ensures that the hash table has sufficient capacity to store the 527 * specified number of mappings, with room to grow. If not, it increases the 528 * capacity as appropriate. Like doubleCapacity, this method moves existing 529 * entries to new buckets as appropriate. Unlike doubleCapacity, this method 530 * can grow the table by factors of 2^n for n > 1. Hopefully, a single call 531 * to this method will be faster than multiple calls to doubleCapacity. 532 * 533 * <p>This method is called only by putAll. 534 */ 535 private void ensureCapacity(int numMappings) { 536 int newCapacity = Collections.roundUpToPowerOfTwo(capacityForInitSize(numMappings)); 537 HashMapEntry<K, V>[] oldTable = table; 538 int oldCapacity = oldTable.length; 539 if (newCapacity <= oldCapacity) { 540 return; 541 } 542 if (newCapacity == oldCapacity * 2) { 543 doubleCapacity(); 544 return; 545 } 546 547 // We're growing by at least 4x, rehash in the obvious way 548 HashMapEntry<K, V>[] newTable = makeTable(newCapacity); 549 if (size != 0) { 550 int newMask = newCapacity - 1; 551 for (int i = 0; i < oldCapacity; i++) { 552 for (HashMapEntry<K, V> e = oldTable[i]; e != null;) { 553 HashMapEntry<K, V> oldNext = e.next; 554 int newIndex = e.hash & newMask; 555 HashMapEntry<K, V> newNext = newTable[newIndex]; 556 newTable[newIndex] = e; 557 e.next = newNext; 558 e = oldNext; 559 } 560 } 561 } 562 } 563 564 /** 565 * Allocate a table of the given capacity and set the threshold accordingly. 566 * @param newCapacity must be a power of two 567 */ 568 private HashMapEntry<K, V>[] makeTable(int newCapacity) { 569 @SuppressWarnings("unchecked") HashMapEntry<K, V>[] newTable 570 = (HashMapEntry<K, V>[]) new HashMapEntry[newCapacity]; 571 table = newTable; 572 threshold = (newCapacity >> 1) + (newCapacity >> 2); // 3/4 capacity 573 return newTable; 574 } 575 576 /** 577 * Doubles the capacity of the hash table. Existing entries are placed in 578 * the correct bucket on the enlarged table. If the current capacity is, 579 * MAXIMUM_CAPACITY, this method is a no-op. Returns the table, which 580 * will be new unless we were already at MAXIMUM_CAPACITY. 581 */ 582 private HashMapEntry<K, V>[] doubleCapacity() { 583 HashMapEntry<K, V>[] oldTable = table; 584 int oldCapacity = oldTable.length; 585 if (oldCapacity == MAXIMUM_CAPACITY) { 586 return oldTable; 587 } 588 int newCapacity = oldCapacity * 2; 589 HashMapEntry<K, V>[] newTable = makeTable(newCapacity); 590 if (size == 0) { 591 return newTable; 592 } 593 594 for (int j = 0; j < oldCapacity; j++) { 595 /* 596 * Rehash the bucket using the minimum number of field writes. 597 * This is the most subtle and delicate code in the class. 598 */ 599 HashMapEntry<K, V> e = oldTable[j]; 600 if (e == null) { 601 continue; 602 } 603 int highBit = e.hash & oldCapacity; 604 HashMapEntry<K, V> broken = null; 605 newTable[j | highBit] = e; 606 for (HashMapEntry<K, V> n = e.next; n != null; e = n, n = n.next) { 607 int nextHighBit = n.hash & oldCapacity; 608 if (nextHighBit != highBit) { 609 if (broken == null) 610 newTable[j | nextHighBit] = n; 611 else 612 broken.next = n; 613 broken = e; 614 highBit = nextHighBit; 615 } 616 } 617 if (broken != null) 618 broken.next = null; 619 } 620 return newTable; 621 } 622 623 /** 624 * Removes the mapping with the specified key from this map. 625 * 626 * @param key 627 * the key of the mapping to remove. 628 * @return the value of the removed mapping or {@code null} if no mapping 629 * for the specified key was found. 630 */ 631 @Override public V remove(Object key) { 632 if (key == null) { 633 return removeNullKey(); 634 } 635 int hash = secondaryHash(key); 636 HashMapEntry<K, V>[] tab = table; 637 int index = hash & (tab.length - 1); 638 for (HashMapEntry<K, V> e = tab[index], prev = null; 639 e != null; prev = e, e = e.next) { 640 if (e.hash == hash && key.equals(e.key)) { 641 if (prev == null) { 642 tab[index] = e.next; 643 } else { 644 prev.next = e.next; 645 } 646 modCount++; 647 size--; 648 postRemove(e); 649 return e.value; 650 } 651 } 652 return null; 653 } 654 655 private V removeNullKey() { 656 HashMapEntry<K, V> e = entryForNullKey; 657 if (e == null) { 658 return null; 659 } 660 entryForNullKey = null; 661 modCount++; 662 size--; 663 postRemove(e); 664 return e.value; 665 } 666 667 /** 668 * Subclass overrides this method to unlink entry. 669 */ 670 void postRemove(HashMapEntry<K, V> e) { } 671 672 /** 673 * Removes all mappings from this hash map, leaving it empty. 674 * 675 * @see #isEmpty 676 * @see #size 677 */ 678 @Override public void clear() { 679 if (size != 0) { 680 Arrays.fill(table, null); 681 entryForNullKey = null; 682 modCount++; 683 size = 0; 684 } 685 } 686 687 /** 688 * Returns a set of the keys contained in this map. The set is backed by 689 * this map so changes to one are reflected by the other. The set does not 690 * support adding. 691 * 692 * @return a set of the keys. 693 */ 694 @Override public Set<K> keySet() { 695 Set<K> ks = keySet; 696 return (ks != null) ? ks : (keySet = new KeySet()); 697 } 698 699 /** 700 * Returns a collection of the values contained in this map. The collection 701 * is backed by this map so changes to one are reflected by the other. The 702 * collection supports remove, removeAll, retainAll and clear operations, 703 * and it does not support add or addAll operations. 704 * <p> 705 * This method returns a collection which is the subclass of 706 * AbstractCollection. The iterator method of this subclass returns a 707 * "wrapper object" over the iterator of map's entrySet(). The {@code size} 708 * method wraps the map's size method and the {@code contains} method wraps 709 * the map's containsValue method. 710 * </p> 711 * <p> 712 * The collection is created when this method is called for the first time 713 * and returned in response to all subsequent calls. This method may return 714 * different collections when multiple concurrent calls occur, since no 715 * synchronization is performed. 716 * </p> 717 * 718 * @return a collection of the values contained in this map. 719 */ 720 @Override public Collection<V> values() { 721 Collection<V> vs = values; 722 return (vs != null) ? vs : (values = new Values()); 723 } 724 725 /** 726 * Returns a set containing all of the mappings in this map. Each mapping is 727 * an instance of {@link Map.Entry}. As the set is backed by this map, 728 * changes in one will be reflected in the other. 729 * 730 * @return a set of the mappings. 731 */ 732 public Set<Entry<K, V>> entrySet() { 733 Set<Entry<K, V>> es = entrySet; 734 return (es != null) ? es : (entrySet = new EntrySet()); 735 } 736 737 static class HashMapEntry<K, V> implements Entry<K, V> { 738 final K key; 739 V value; 740 final int hash; 741 HashMapEntry<K, V> next; 742 743 HashMapEntry(K key, V value, int hash, HashMapEntry<K, V> next) { 744 this.key = key; 745 this.value = value; 746 this.hash = hash; 747 this.next = next; 748 } 749 750 public final K getKey() { 751 return key; 752 } 753 754 public final V getValue() { 755 return value; 756 } 757 758 public final V setValue(V value) { 759 V oldValue = this.value; 760 this.value = value; 761 return oldValue; 762 } 763 764 @Override public final boolean equals(Object o) { 765 if (!(o instanceof Entry)) { 766 return false; 767 } 768 Entry<?, ?> e = (Entry<?, ?>) o; 769 return Objects.equal(e.getKey(), key) 770 && Objects.equal(e.getValue(), value); 771 } 772 773 @Override public final int hashCode() { 774 return (key == null ? 0 : key.hashCode()) ^ 775 (value == null ? 0 : value.hashCode()); 776 } 777 778 @Override public final String toString() { 779 return key + "=" + value; 780 } 781 } 782 783 private abstract class HashIterator { 784 int nextIndex; 785 HashMapEntry<K, V> nextEntry = entryForNullKey; 786 HashMapEntry<K, V> lastEntryReturned; 787 int expectedModCount = modCount; 788 789 HashIterator() { 790 if (nextEntry == null) { 791 HashMapEntry<K, V>[] tab = table; 792 HashMapEntry<K, V> next = null; 793 while (next == null && nextIndex < tab.length) { 794 next = tab[nextIndex++]; 795 } 796 nextEntry = next; 797 } 798 } 799 800 public boolean hasNext() { 801 return nextEntry != null; 802 } 803 804 HashMapEntry<K, V> nextEntry() { 805 if (modCount != expectedModCount) 806 throw new ConcurrentModificationException(); 807 if (nextEntry == null) 808 throw new NoSuchElementException(); 809 810 HashMapEntry<K, V> entryToReturn = nextEntry; 811 HashMapEntry<K, V>[] tab = table; 812 HashMapEntry<K, V> next = entryToReturn.next; 813 while (next == null && nextIndex < tab.length) { 814 next = tab[nextIndex++]; 815 } 816 nextEntry = next; 817 return lastEntryReturned = entryToReturn; 818 } 819 820 public void remove() { 821 if (lastEntryReturned == null) 822 throw new IllegalStateException(); 823 if (modCount != expectedModCount) 824 throw new ConcurrentModificationException(); 825 HashMap.this.remove(lastEntryReturned.key); 826 lastEntryReturned = null; 827 expectedModCount = modCount; 828 } 829 } 830 831 private final class KeyIterator extends HashIterator 832 implements Iterator<K> { 833 public K next() { return nextEntry().key; } 834 } 835 836 private final class ValueIterator extends HashIterator 837 implements Iterator<V> { 838 public V next() { return nextEntry().value; } 839 } 840 841 private final class EntryIterator extends HashIterator 842 implements Iterator<Entry<K, V>> { 843 public Entry<K, V> next() { return nextEntry(); } 844 } 845 846 /** 847 * Returns true if this map contains the specified mapping. 848 */ 849 private boolean containsMapping(Object key, Object value) { 850 if (key == null) { 851 HashMapEntry<K, V> e = entryForNullKey; 852 return e != null && Objects.equal(value, e.value); 853 } 854 855 int hash = secondaryHash(key); 856 HashMapEntry<K, V>[] tab = table; 857 int index = hash & (tab.length - 1); 858 for (HashMapEntry<K, V> e = tab[index]; e != null; e = e.next) { 859 if (e.hash == hash && key.equals(e.key)) { 860 return Objects.equal(value, e.value); 861 } 862 } 863 return false; // No entry for key 864 } 865 866 /** 867 * Removes the mapping from key to value and returns true if this mapping 868 * exists; otherwise, returns does nothing and returns false. 869 */ 870 private boolean removeMapping(Object key, Object value) { 871 if (key == null) { 872 HashMapEntry<K, V> e = entryForNullKey; 873 if (e == null || !Objects.equal(value, e.value)) { 874 return false; 875 } 876 entryForNullKey = null; 877 modCount++; 878 size--; 879 postRemove(e); 880 return true; 881 } 882 883 int hash = secondaryHash(key); 884 HashMapEntry<K, V>[] tab = table; 885 int index = hash & (tab.length - 1); 886 for (HashMapEntry<K, V> e = tab[index], prev = null; 887 e != null; prev = e, e = e.next) { 888 if (e.hash == hash && key.equals(e.key)) { 889 if (!Objects.equal(value, e.value)) { 890 return false; // Map has wrong value for key 891 } 892 if (prev == null) { 893 tab[index] = e.next; 894 } else { 895 prev.next = e.next; 896 } 897 modCount++; 898 size--; 899 postRemove(e); 900 return true; 901 } 902 } 903 return false; // No entry for key 904 } 905 906 // Subclass (LinkedHashMap) overrides these for correct iteration order 907 Iterator<K> newKeyIterator() { return new KeyIterator(); } 908 Iterator<V> newValueIterator() { return new ValueIterator(); } 909 Iterator<Entry<K, V>> newEntryIterator() { return new EntryIterator(); } 910 911 private final class KeySet extends AbstractSet<K> { 912 public Iterator<K> iterator() { 913 return newKeyIterator(); 914 } 915 public int size() { 916 return size; 917 } 918 public boolean isEmpty() { 919 return size == 0; 920 } 921 public boolean contains(Object o) { 922 return containsKey(o); 923 } 924 public boolean remove(Object o) { 925 int oldSize = size; 926 HashMap.this.remove(o); 927 return size != oldSize; 928 } 929 public void clear() { 930 HashMap.this.clear(); 931 } 932 } 933 934 private final class Values extends AbstractCollection<V> { 935 public Iterator<V> iterator() { 936 return newValueIterator(); 937 } 938 public int size() { 939 return size; 940 } 941 public boolean isEmpty() { 942 return size == 0; 943 } 944 public boolean contains(Object o) { 945 return containsValue(o); 946 } 947 public void clear() { 948 HashMap.this.clear(); 949 } 950 } 951 952 private final class EntrySet extends AbstractSet<Entry<K, V>> { 953 public Iterator<Entry<K, V>> iterator() { 954 return newEntryIterator(); 955 } 956 public boolean contains(Object o) { 957 if (!(o instanceof Entry)) 958 return false; 959 Entry<?, ?> e = (Entry<?, ?>) o; 960 return containsMapping(e.getKey(), e.getValue()); 961 } 962 public boolean remove(Object o) { 963 if (!(o instanceof Entry)) 964 return false; 965 Entry<?, ?> e = (Entry<?, ?>)o; 966 return removeMapping(e.getKey(), e.getValue()); 967 } 968 public int size() { 969 return size; 970 } 971 public boolean isEmpty() { 972 return size == 0; 973 } 974 public void clear() { 975 HashMap.this.clear(); 976 } 977 } 978 979 private static final long serialVersionUID = 362498820763181265L; 980 981 private static final ObjectStreamField[] serialPersistentFields = { 982 new ObjectStreamField("loadFactor", float.class) 983 }; 984 985 private void writeObject(ObjectOutputStream stream) throws IOException { 986 // Emulate loadFactor field for other implementations to read 987 ObjectOutputStream.PutField fields = stream.putFields(); 988 fields.put("loadFactor", DEFAULT_LOAD_FACTOR); 989 stream.writeFields(); 990 991 stream.writeInt(table.length); // Capacity 992 stream.writeInt(size); 993 for (Entry<K, V> e : entrySet()) { 994 stream.writeObject(e.getKey()); 995 stream.writeObject(e.getValue()); 996 } 997 } 998 999 private void readObject(ObjectInputStream stream) throws IOException, 1000 ClassNotFoundException { 1001 stream.defaultReadObject(); 1002 int capacity = stream.readInt(); 1003 if (capacity < 0) { 1004 throw new InvalidObjectException("Capacity: " + capacity); 1005 } 1006 if (capacity < MINIMUM_CAPACITY) { 1007 capacity = MINIMUM_CAPACITY; 1008 } else if (capacity > MAXIMUM_CAPACITY) { 1009 capacity = MAXIMUM_CAPACITY; 1010 } else { 1011 capacity = Collections.roundUpToPowerOfTwo(capacity); 1012 } 1013 makeTable(capacity); 1014 1015 int size = stream.readInt(); 1016 if (size < 0) { 1017 throw new InvalidObjectException("Size: " + size); 1018 } 1019 1020 init(); // Give subclass (LinkedHashMap) a chance to initialize itself 1021 for (int i = 0; i < size; i++) { 1022 @SuppressWarnings("unchecked") K key = (K) stream.readObject(); 1023 @SuppressWarnings("unchecked") V val = (V) stream.readObject(); 1024 constructorPut(key, val); 1025 } 1026 } 1027 } 1028