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 // BEGIN android-note 19 // Completely different implementation from harmony. Runs much faster. 20 // BEGIN android-note 21 22 package java.util; 23 24 import java.io.IOException; 25 import java.io.InvalidObjectException; 26 import java.io.ObjectInputStream; 27 import java.io.ObjectOutputStream; 28 import java.io.ObjectStreamField; 29 import java.io.Serializable; 30 31 /** 32 * Hashtable is a synchronized implementation of {@link Map}. All optional operations are supported. 33 * 34 * <p>Neither keys nor values can be null. (Use {@code HashMap} or {@code LinkedHashMap} if you 35 * need null keys or values.) 36 * 37 * @param <K> the type of keys maintained by this map 38 * @param <V> the type of mapped values 39 * @see HashMap 40 */ 41 public class Hashtable<K, V> extends Dictionary<K, V> 42 implements Map<K, V>, Cloneable, Serializable { 43 /** 44 * Min capacity (other than zero) for a Hashtable. Must be a power of two 45 * greater than 1 (and less than 1 << 30). 46 */ 47 private static final int MINIMUM_CAPACITY = 4; 48 49 /** 50 * Max capacity for a Hashtable. Must be a power of two >= MINIMUM_CAPACITY. 51 */ 52 private static final int MAXIMUM_CAPACITY = 1 << 30; 53 54 /** 55 * An empty table shared by all zero-capacity maps (typically from default 56 * constructor). It is never written to, and replaced on first put. Its size 57 * is set to half the minimum, so that the first resize will create a 58 * minimum-sized table. 59 */ 60 private static final Entry[] EMPTY_TABLE 61 = new HashtableEntry[MINIMUM_CAPACITY >>> 1]; 62 63 /** 64 * The default load factor. Note that this implementation ignores the 65 * load factor, but cannot do away with it entirely because it's 66 * mentioned in the API. 67 * 68 * <p>Note that this constant has no impact on the behavior of the program, 69 * but it is emitted as part of the serialized form. The load factor of 70 * .75 is hardwired into the program, which uses cheap shifts in place of 71 * expensive division. 72 */ 73 private static final float DEFAULT_LOAD_FACTOR = .75F; 74 75 /** 76 * The hash table. 77 */ 78 private transient HashtableEntry<K, V>[] table; 79 80 /** 81 * The number of mappings in this hash map. 82 */ 83 private transient int size; 84 85 /** 86 * Incremented by "structural modifications" to allow (best effort) 87 * detection of concurrent modification. 88 */ 89 private transient int modCount; 90 91 /** 92 * The table is rehashed when its size exceeds this threshold. 93 * The value of this field is generally .75 * capacity, except when 94 * the capacity is zero, as described in the EMPTY_TABLE declaration 95 * above. 96 */ 97 private transient int threshold; 98 99 // Views - lazily initialized 100 private transient Set<K> keySet; 101 private transient Set<Entry<K, V>> entrySet; 102 private transient Collection<V> values; 103 104 /** 105 * Constructs a new {@code Hashtable} using the default capacity and load 106 * factor. 107 */ 108 @SuppressWarnings("unchecked") Hashtable()109 public Hashtable() { 110 table = (HashtableEntry<K, V>[]) EMPTY_TABLE; 111 threshold = -1; // Forces first put invocation to replace EMPTY_TABLE 112 } 113 114 /** 115 * Constructs a new {@code Hashtable} using the specified capacity and the 116 * default load factor. 117 * 118 * @param capacity 119 * the initial capacity. 120 */ Hashtable(int capacity)121 public Hashtable(int capacity) { 122 if (capacity < 0) { 123 throw new IllegalArgumentException("Capacity: " + capacity); 124 } 125 126 if (capacity == 0) { 127 @SuppressWarnings("unchecked") 128 HashtableEntry<K, V>[] tab = (HashtableEntry<K, V>[]) EMPTY_TABLE; 129 table = tab; 130 threshold = -1; // Forces first put() to replace EMPTY_TABLE 131 return; 132 } 133 134 if (capacity < MINIMUM_CAPACITY) { 135 capacity = MINIMUM_CAPACITY; 136 } else if (capacity > MAXIMUM_CAPACITY) { 137 capacity = MAXIMUM_CAPACITY; 138 } else { 139 capacity = roundUpToPowerOfTwo(capacity); 140 } 141 makeTable(capacity); 142 } 143 144 /** 145 * Constructs a new {@code Hashtable} using the specified capacity and load 146 * factor. 147 * 148 * @param capacity 149 * the initial capacity. 150 * @param loadFactor 151 * the initial load factor. 152 */ Hashtable(int capacity, float loadFactor)153 public Hashtable(int capacity, float loadFactor) { 154 this(capacity); 155 156 if (loadFactor <= 0 || Float.isNaN(loadFactor)) { 157 throw new IllegalArgumentException("Load factor: " + loadFactor); 158 } 159 160 /* 161 * Note that this implementation ignores loadFactor; it always uses 162 * a load factor of 3/4. This simplifies the code and generally 163 * improves performance. 164 */ 165 } 166 167 /** 168 * Constructs a new instance of {@code Hashtable} containing the mappings 169 * from the specified map. 170 * 171 * @param map 172 * the mappings to add. 173 */ Hashtable(Map<? extends K, ? extends V> map)174 public Hashtable(Map<? extends K, ? extends V> map) { 175 this(capacityForInitSize(map.size())); 176 constructorPutAll(map); 177 } 178 179 /** 180 * Inserts all of the elements of map into this Hashtable in a manner 181 * suitable for use by constructors and pseudo-constructors (i.e., clone, 182 * readObject). 183 */ constructorPutAll(Map<? extends K, ? extends V> map)184 private void constructorPutAll(Map<? extends K, ? extends V> map) { 185 for (Entry<? extends K, ? extends V> e : map.entrySet()) { 186 constructorPut(e.getKey(), e.getValue()); 187 } 188 } 189 190 /** 191 * Returns an appropriate capacity for the specified initial size. Does 192 * not round the result up to a power of two; the caller must do this! 193 * The returned value will be between 0 and MAXIMUM_CAPACITY (inclusive). 194 */ capacityForInitSize(int size)195 private static int capacityForInitSize(int size) { 196 int result = (size >> 1) + size; // Multiply by 3/2 to allow for growth 197 198 // boolean expr is equivalent to result >= 0 && result<MAXIMUM_CAPACITY 199 return (result & ~(MAXIMUM_CAPACITY-1))==0 ? result : MAXIMUM_CAPACITY; 200 } 201 202 /** 203 * Returns a new {@code Hashtable} with the same key/value pairs, capacity 204 * and load factor. 205 * 206 * @return a shallow copy of this {@code Hashtable}. 207 * @see java.lang.Cloneable 208 */ 209 @SuppressWarnings("unchecked") clone()210 @Override public synchronized Object clone() { 211 /* 212 * This could be made more efficient. It unnecessarily hashes all of 213 * the elements in the map. 214 */ 215 Hashtable<K, V> result; 216 try { 217 result = (Hashtable<K, V>) super.clone(); 218 } catch (CloneNotSupportedException e) { 219 throw new AssertionError(e); 220 } 221 222 // Restore clone to empty state, retaining our capacity and threshold 223 result.makeTable(table.length); 224 result.size = 0; 225 result.keySet = null; 226 result.entrySet = null; 227 result.values = null; 228 229 result.constructorPutAll(this); 230 return result; 231 } 232 233 /** 234 * Returns true if this {@code Hashtable} has no key/value pairs. 235 * 236 * @return {@code true} if this {@code Hashtable} has no key/value pairs, 237 * {@code false} otherwise. 238 * @see #size 239 */ isEmpty()240 public synchronized boolean isEmpty() { 241 return size == 0; 242 } 243 244 /** 245 * Returns the number of key/value pairs in this {@code Hashtable}. 246 * 247 * @return the number of key/value pairs in this {@code Hashtable}. 248 * @see #elements 249 * @see #keys 250 */ size()251 public synchronized int size() { 252 return size; 253 } 254 255 /** 256 * Returns the value associated with the specified key in this 257 * {@code Hashtable}. 258 * 259 * @param key 260 * the key of the value returned. 261 * @return the value associated with the specified key, or {@code null} if 262 * the specified key does not exist. 263 * @see #put 264 */ get(Object key)265 public synchronized V get(Object key) { 266 // Doug Lea's supplemental secondaryHash function (inlined) 267 int hash = key.hashCode(); 268 hash ^= (hash >>> 20) ^ (hash >>> 12); 269 hash ^= (hash >>> 7) ^ (hash >>> 4); 270 271 HashtableEntry<K, V>[] tab = table; 272 for (HashtableEntry<K, V> e = tab[hash & (tab.length - 1)]; 273 e != null; e = e.next) { 274 K eKey = e.key; 275 if (eKey == key || (e.hash == hash && key.equals(eKey))) { 276 return e.value; 277 } 278 } 279 return null; 280 } 281 282 /** 283 * Returns true if this {@code Hashtable} contains the specified object as a 284 * key of one of the key/value pairs. 285 * 286 * @param key 287 * the object to look for as a key in this {@code Hashtable}. 288 * @return {@code true} if object is a key in this {@code Hashtable}, 289 * {@code false} otherwise. 290 * @see #contains 291 * @see java.lang.Object#equals 292 */ containsKey(Object key)293 public synchronized boolean containsKey(Object key) { 294 // Doug Lea's supplemental secondaryHash function (inlined) 295 int hash = key.hashCode(); 296 hash ^= (hash >>> 20) ^ (hash >>> 12); 297 hash ^= (hash >>> 7) ^ (hash >>> 4); 298 299 HashtableEntry<K, V>[] tab = table; 300 for (HashtableEntry<K, V> e = tab[hash & (tab.length - 1)]; 301 e != null; e = e.next) { 302 K eKey = e.key; 303 if (eKey == key || (e.hash == hash && key.equals(eKey))) { 304 return true; 305 } 306 } 307 return false; 308 } 309 310 /** 311 * Searches this {@code Hashtable} for the specified value. 312 * 313 * @param value 314 * the object to search for. 315 * @return {@code true} if {@code value} is a value of this 316 * {@code Hashtable}, {@code false} otherwise. 317 */ containsValue(Object value)318 public synchronized boolean containsValue(Object value) { 319 if (value == null) { 320 throw new NullPointerException(); 321 } 322 323 HashtableEntry[] tab = table; 324 int len = tab.length; 325 326 for (int i = 0; i < len; i++) { 327 for (HashtableEntry e = tab[i]; e != null; e = e.next) { 328 if (value.equals(e.value)) { 329 return true; 330 } 331 } 332 } 333 return false; 334 } 335 336 /** 337 * Returns true if this {@code Hashtable} contains the specified object as 338 * the value of at least one of the key/value pairs. 339 * 340 * @param value 341 * the object to look for as a value in this {@code Hashtable}. 342 * @return {@code true} if object is a value in this {@code Hashtable}, 343 * {@code false} otherwise. 344 * @see #containsKey 345 * @see java.lang.Object#equals 346 */ contains(Object value)347 public boolean contains(Object value) { 348 return containsValue(value); 349 } 350 351 /** 352 * Associate the specified value with the specified key in this 353 * {@code Hashtable}. If the key already exists, the old value is replaced. 354 * The key and value cannot be null. 355 * 356 * @param key 357 * the key to add. 358 * @param value 359 * the value to add. 360 * @return the old value associated with the specified key, or {@code null} 361 * if the key did not exist. 362 * @see #elements 363 * @see #get 364 * @see #keys 365 * @see java.lang.Object#equals 366 */ put(K key, V value)367 public synchronized V put(K key, V value) { 368 if (value == null) { 369 throw new NullPointerException(); 370 } 371 int hash = secondaryHash(key.hashCode()); 372 HashtableEntry<K, V>[] tab = table; 373 int index = hash & (tab.length - 1); 374 HashtableEntry<K, V> first = tab[index]; 375 for (HashtableEntry<K, V> e = first; e != null; e = e.next) { 376 if (e.hash == hash && key.equals(e.key)) { 377 V oldValue = e.value; 378 e.value = value; 379 return oldValue; 380 } 381 } 382 383 // No entry for key is present; create one 384 modCount++; 385 if (size++ > threshold) { 386 rehash(); // Does nothing!! 387 tab = doubleCapacity(); 388 index = hash & (tab.length - 1); 389 first = tab[index]; 390 } 391 tab[index] = new HashtableEntry<K, V>(key, value, hash, first); 392 return null; 393 } 394 395 /** 396 * This method is just like put, except that it doesn't do things that 397 * are inappropriate or unnecessary for constructors and pseudo-constructors 398 * (i.e., clone, readObject). In particular, this method does not check to 399 * ensure that capacity is sufficient, and does not increment modCount. 400 */ constructorPut(K key, V value)401 private void constructorPut(K key, V value) { 402 if (value == null) { 403 throw new NullPointerException(); 404 } 405 int hash = secondaryHash(key.hashCode()); 406 HashtableEntry<K, V>[] tab = table; 407 int index = hash & (tab.length - 1); 408 HashtableEntry<K, V> first = tab[index]; 409 for (HashtableEntry<K, V> e = first; e != null; e = e.next) { 410 if (e.hash == hash && key.equals(e.key)) { 411 e.value = value; 412 return; 413 } 414 } 415 416 // No entry for key is present; create one 417 tab[index] = new HashtableEntry<K, V>(key, value, hash, first); 418 size++; 419 } 420 421 /** 422 * Copies every mapping to this {@code Hashtable} from the specified map. 423 * 424 * @param map 425 * the map to copy mappings from. 426 */ putAll(Map<? extends K, ? extends V> map)427 public synchronized void putAll(Map<? extends K, ? extends V> map) { 428 ensureCapacity(map.size()); 429 for (Entry<? extends K, ? extends V> e : map.entrySet()) { 430 put(e.getKey(), e.getValue()); 431 } 432 } 433 434 /** 435 * Ensures that the hash table has sufficient capacity to store the 436 * specified number of mappings, with room to grow. If not, it increases the 437 * capacity as appropriate. Like doubleCapacity, this method moves existing 438 * entries to new buckets as appropriate. Unlike doubleCapacity, this method 439 * can grow the table by factors of 2^n for n > 1. Hopefully, a single call 440 * to this method will be faster than multiple calls to doubleCapacity. 441 * 442 * <p>This method is called only by putAll. 443 */ ensureCapacity(int numMappings)444 private void ensureCapacity(int numMappings) { 445 int newCapacity = roundUpToPowerOfTwo(capacityForInitSize(numMappings)); 446 HashtableEntry<K, V>[] oldTable = table; 447 int oldCapacity = oldTable.length; 448 if (newCapacity <= oldCapacity) { 449 return; 450 } 451 452 rehash(); // Does nothing!! 453 454 if (newCapacity == oldCapacity << 1) { 455 doubleCapacity(); 456 return; 457 } 458 459 // We're growing by at least 4x, rehash in the obvious way 460 HashtableEntry<K, V>[] newTable = makeTable(newCapacity); 461 if (size != 0) { 462 int newMask = newCapacity - 1; 463 for (int i = 0; i < oldCapacity; i++) { 464 for (HashtableEntry<K, V> e = oldTable[i]; e != null;) { 465 HashtableEntry<K, V> oldNext = e.next; 466 int newIndex = e.hash & newMask; 467 HashtableEntry<K, V> newNext = newTable[newIndex]; 468 newTable[newIndex] = e; 469 e.next = newNext; 470 e = oldNext; 471 } 472 } 473 } 474 } 475 476 /** 477 * Increases the capacity of this {@code Hashtable}. This method is called 478 * when the size of this {@code Hashtable} exceeds the load factor. 479 */ rehash()480 protected void rehash() { 481 /* 482 * This method has no testable semantics, other than that it gets 483 * called from time to time. 484 */ 485 } 486 487 /** 488 * Allocate a table of the given capacity and set the threshold accordingly. 489 * @param newCapacity must be a power of two 490 */ makeTable(int newCapacity)491 private HashtableEntry<K, V>[] makeTable(int newCapacity) { 492 @SuppressWarnings("unchecked") HashtableEntry<K, V>[] newTable 493 = (HashtableEntry<K, V>[]) new HashtableEntry[newCapacity]; 494 table = newTable; 495 threshold = (newCapacity >> 1) + (newCapacity >> 2); // 3/4 capacity 496 return newTable; 497 } 498 499 /** 500 * Doubles the capacity of the hash table. Existing entries are placed in 501 * the correct bucket on the enlarged table. If the current capacity is, 502 * MAXIMUM_CAPACITY, this method is a no-op. Returns the table, which 503 * will be new unless we were already at MAXIMUM_CAPACITY. 504 */ doubleCapacity()505 private HashtableEntry<K, V>[] doubleCapacity() { 506 HashtableEntry<K, V>[] oldTable = table; 507 int oldCapacity = oldTable.length; 508 if (oldCapacity == MAXIMUM_CAPACITY) { 509 return oldTable; 510 } 511 int newCapacity = oldCapacity << 1; 512 HashtableEntry<K, V>[] newTable = makeTable(newCapacity); 513 if (size == 0) { 514 return newTable; 515 } 516 517 for (int j = 0; j < oldCapacity; j++) { 518 /* 519 * Rehash the bucket using the minimum number of field writes. 520 * This is the most subtle and delicate code in the class. 521 */ 522 HashtableEntry<K, V> e = oldTable[j]; 523 if (e == null) { 524 continue; 525 } 526 int highBit = e.hash & oldCapacity; 527 HashtableEntry<K, V> broken = null; 528 newTable[j | highBit] = e; 529 for (HashtableEntry<K,V> n = e.next; n != null; e = n, n = n.next) { 530 int nextHighBit = n.hash & oldCapacity; 531 if (nextHighBit != highBit) { 532 if (broken == null) 533 newTable[j | nextHighBit] = n; 534 else 535 broken.next = n; 536 broken = e; 537 highBit = nextHighBit; 538 } 539 } 540 if (broken != null) 541 broken.next = null; 542 } 543 return newTable; 544 } 545 546 /** 547 * Removes the key/value pair with the specified key from this 548 * {@code Hashtable}. 549 * 550 * @param key 551 * the key to remove. 552 * @return the value associated with the specified key, or {@code null} if 553 * the specified key did not exist. 554 * @see #get 555 * @see #put 556 */ remove(Object key)557 public synchronized V remove(Object key) { 558 int hash = secondaryHash(key.hashCode()); 559 HashtableEntry<K, V>[] tab = table; 560 int index = hash & (tab.length - 1); 561 for (HashtableEntry<K, V> e = tab[index], prev = null; 562 e != null; prev = e, e = e.next) { 563 if (e.hash == hash && key.equals(e.key)) { 564 if (prev == null) { 565 tab[index] = e.next; 566 } else { 567 prev.next = e.next; 568 } 569 modCount++; 570 size--; 571 return e.value; 572 } 573 } 574 return null; 575 } 576 577 /** 578 * Removes all key/value pairs from this {@code Hashtable}, leaving the 579 * size zero and the capacity unchanged. 580 * 581 * @see #isEmpty 582 * @see #size 583 */ clear()584 public synchronized void clear() { 585 if (size != 0) { 586 Arrays.fill(table, null); 587 modCount++; 588 size = 0; 589 } 590 } 591 592 /** 593 * Returns a set of the keys contained in this {@code Hashtable}. The set 594 * is backed by this {@code Hashtable} so changes to one are reflected by 595 * the other. The set does not support adding. 596 * 597 * @return a set of the keys. 598 */ keySet()599 public synchronized Set<K> keySet() { 600 Set<K> ks = keySet; 601 return (ks != null) ? ks : (keySet = new KeySet()); 602 } 603 604 /** 605 * Returns a collection of the values contained in this {@code Hashtable}. 606 * The collection is backed by this {@code Hashtable} so changes to one are 607 * reflected by the other. The collection does not support adding. 608 * 609 * @return a collection of the values. 610 */ values()611 public synchronized Collection<V> values() { 612 Collection<V> vs = values; 613 return (vs != null) ? vs : (values = new Values()); 614 } 615 616 /** 617 * Returns a set of the mappings contained in this {@code Hashtable}. Each 618 * element in the set is a {@link Map.Entry}. The set is backed by this 619 * {@code Hashtable} so changes to one are reflected by the other. The set 620 * does not support adding. 621 * 622 * @return a set of the mappings. 623 */ entrySet()624 public synchronized Set<Entry<K, V>> entrySet() { 625 Set<Entry<K, V>> es = entrySet; 626 return (es != null) ? es : (entrySet = new EntrySet()); 627 } 628 629 630 /** 631 * Returns an enumeration on the keys of this {@code Hashtable} instance. 632 * The results of the enumeration may be affected if the contents of this 633 * {@code Hashtable} are modified. 634 * 635 * @return an enumeration of the keys of this {@code Hashtable}. 636 * @see #elements 637 * @see #size 638 * @see Enumeration 639 */ keys()640 public synchronized Enumeration<K> keys() { 641 return new KeyEnumeration(); 642 } 643 644 /** 645 * Returns an enumeration on the values of this {@code Hashtable}. The 646 * results of the Enumeration may be affected if the contents of this 647 * {@code Hashtable} are modified. 648 * 649 * @return an enumeration of the values of this {@code Hashtable}. 650 * @see #keys 651 * @see #size 652 * @see Enumeration 653 */ elements()654 public synchronized Enumeration<V> elements() { 655 return new ValueEnumeration(); 656 } 657 658 /** 659 * Note: technically the methods of this class should synchronize the 660 * backing map. However, this would require them to have a reference 661 * to it, which would cause considerable bloat. Moreover, the RI 662 * behaves the same way. 663 */ 664 private static class HashtableEntry<K, V> implements Entry<K, V> { 665 final K key; 666 V value; 667 final int hash; 668 HashtableEntry<K, V> next; 669 HashtableEntry(K key, V value, int hash, HashtableEntry<K, V> next)670 HashtableEntry(K key, V value, int hash, HashtableEntry<K, V> next) { 671 this.key = key; 672 this.value = value; 673 this.hash = hash; 674 this.next = next; 675 } 676 getKey()677 public final K getKey() { 678 return key; 679 } 680 getValue()681 public final V getValue() { 682 return value; 683 } 684 setValue(V value)685 public final V setValue(V value) { 686 if (value == null) { 687 throw new NullPointerException(); 688 } 689 V oldValue = this.value; 690 this.value = value; 691 return oldValue; 692 } 693 equals(Object o)694 @Override public final boolean equals(Object o) { 695 if (!(o instanceof Entry)) { 696 return false; 697 } 698 Entry<?, ?> e = (Entry<?, ?>) o; 699 return key.equals(e.getKey()) && value.equals(e.getValue()); 700 } 701 hashCode()702 @Override public final int hashCode() { 703 return key.hashCode() ^ value.hashCode(); 704 } 705 toString()706 @Override public final String toString() { 707 return key + "=" + value; 708 } 709 } 710 711 private abstract class HashIterator { 712 int nextIndex; 713 HashtableEntry<K, V> nextEntry; 714 HashtableEntry<K, V> lastEntryReturned; 715 int expectedModCount = modCount; 716 HashIterator()717 HashIterator() { 718 HashtableEntry<K, V>[] tab = table; 719 HashtableEntry<K, V> next = null; 720 while (next == null && nextIndex < tab.length) { 721 next = tab[nextIndex++]; 722 } 723 nextEntry = next; 724 } 725 hasNext()726 public boolean hasNext() { 727 return nextEntry != null; 728 } 729 nextEntry()730 HashtableEntry<K, V> nextEntry() { 731 if (modCount != expectedModCount) 732 throw new ConcurrentModificationException(); 733 if (nextEntry == null) 734 throw new NoSuchElementException(); 735 736 HashtableEntry<K, V> entryToReturn = nextEntry; 737 HashtableEntry<K, V>[] tab = table; 738 HashtableEntry<K, V> next = entryToReturn.next; 739 while (next == null && nextIndex < tab.length) { 740 next = tab[nextIndex++]; 741 } 742 nextEntry = next; 743 return lastEntryReturned = entryToReturn; 744 } 745 nextEntryNotFailFast()746 HashtableEntry<K, V> nextEntryNotFailFast() { 747 if (nextEntry == null) 748 throw new NoSuchElementException(); 749 750 HashtableEntry<K, V> entryToReturn = nextEntry; 751 HashtableEntry<K, V>[] tab = table; 752 HashtableEntry<K, V> next = entryToReturn.next; 753 while (next == null && nextIndex < tab.length) { 754 next = tab[nextIndex++]; 755 } 756 nextEntry = next; 757 return lastEntryReturned = entryToReturn; 758 } 759 remove()760 public void remove() { 761 if (lastEntryReturned == null) 762 throw new IllegalStateException(); 763 if (modCount != expectedModCount) 764 throw new ConcurrentModificationException(); 765 Hashtable.this.remove(lastEntryReturned.key); 766 lastEntryReturned = null; 767 expectedModCount = modCount; 768 } 769 } 770 771 private final class KeyIterator extends HashIterator 772 implements Iterator<K> { next()773 public K next() { return nextEntry().key; } 774 } 775 776 private final class ValueIterator extends HashIterator 777 implements Iterator<V> { next()778 public V next() { return nextEntry().value; } 779 } 780 781 private final class EntryIterator extends HashIterator 782 implements Iterator<Entry<K, V>> { next()783 public Entry<K, V> next() { return nextEntry(); } 784 } 785 786 private final class KeyEnumeration extends HashIterator 787 implements Enumeration<K> { hasMoreElements()788 public boolean hasMoreElements() { return hasNext(); } nextElement()789 public K nextElement() { return nextEntryNotFailFast().key; } 790 } 791 792 private final class ValueEnumeration extends HashIterator 793 implements Enumeration<V> { hasMoreElements()794 public boolean hasMoreElements() { return hasNext(); } nextElement()795 public V nextElement() { return nextEntryNotFailFast().value; } 796 } 797 798 /** 799 * Returns true if this map contains the specified mapping. 800 */ containsMapping(Object key, Object value)801 private synchronized boolean containsMapping(Object key, Object value) { 802 int hash = secondaryHash(key.hashCode()); 803 HashtableEntry<K, V>[] tab = table; 804 int index = hash & (tab.length - 1); 805 for (HashtableEntry<K, V> e = tab[index]; e != null; e = e.next) { 806 if (e.hash == hash && e.key.equals(key)) { 807 return e.value.equals(value); 808 } 809 } 810 return false; // No entry for key 811 } 812 813 /** 814 * Removes the mapping from key to value and returns true if this mapping 815 * exists; otherwise, returns does nothing and returns false. 816 */ removeMapping(Object key, Object value)817 private synchronized boolean removeMapping(Object key, Object value) { 818 int hash = secondaryHash(key.hashCode()); 819 HashtableEntry<K, V>[] tab = table; 820 int index = hash & (tab.length - 1); 821 for (HashtableEntry<K, V> e = tab[index], prev = null; 822 e != null; prev = e, e = e.next) { 823 if (e.hash == hash && e.key.equals(key)) { 824 if (!e.value.equals(value)) { 825 return false; // Map has wrong value for key 826 } 827 if (prev == null) { 828 tab[index] = e.next; 829 } else { 830 prev.next = e.next; 831 } 832 modCount++; 833 size--; 834 return true; 835 } 836 } 837 return false; // No entry for key 838 } 839 840 /** 841 * Compares this {@code Hashtable} with the specified object and indicates 842 * if they are equal. In order to be equal, {@code object} must be an 843 * instance of Map and contain the same key/value pairs. 844 * 845 * @param object 846 * the object to compare with this object. 847 * @return {@code true} if the specified object is equal to this Map, 848 * {@code false} otherwise. 849 * @see #hashCode 850 */ equals(Object object)851 @Override public synchronized boolean equals(Object object) { 852 return (object instanceof Map) && 853 entrySet().equals(((Map<?, ?>)object).entrySet()); 854 } 855 hashCode()856 @Override public synchronized int hashCode() { 857 int result = 0; 858 for (Entry<K, V> e : entrySet()) { 859 K key = e.getKey(); 860 V value = e.getValue(); 861 if (key == this || value == this) { 862 continue; 863 } 864 result += (key != null ? key.hashCode() : 0) 865 ^ (value != null ? value.hashCode() : 0); 866 } 867 return result; 868 } 869 870 /** 871 * A rough estimate of the number of characters per entry, for use 872 * when creating a string buffer in the toString method. 873 */ 874 private static final int CHARS_PER_ENTRY = 15; 875 876 /** 877 * Returns the string representation of this {@code Hashtable}. 878 * 879 * @return the string representation of this {@code Hashtable}. 880 */ toString()881 @Override public synchronized String toString() { 882 StringBuilder result = new StringBuilder(CHARS_PER_ENTRY * size); 883 result.append('{'); 884 Iterator<Entry<K, V>> i = entrySet().iterator(); 885 boolean hasMore = i.hasNext(); 886 while (hasMore) { 887 Entry<K, V> entry = i.next(); 888 889 K key = entry.getKey(); 890 result.append(key == this ? "(this Map)" : key.toString()); 891 892 result.append('='); 893 894 V value = entry.getValue(); 895 result.append(value == this ? "(this Map)" : value.toString()); 896 897 if (hasMore = i.hasNext()) { 898 result.append(", "); 899 } 900 } 901 902 result.append('}'); 903 return result.toString(); 904 } 905 906 private final class KeySet extends AbstractSet<K> { iterator()907 public Iterator<K> iterator() { 908 return new KeyIterator(); 909 } size()910 public int size() { 911 return Hashtable.this.size(); 912 } contains(Object o)913 public boolean contains(Object o) { 914 return containsKey(o); 915 } remove(Object o)916 public boolean remove(Object o) { 917 synchronized (Hashtable.this) { 918 int oldSize = size; 919 Hashtable.this.remove(o); 920 return size != oldSize; 921 } 922 } clear()923 public void clear() { 924 Hashtable.this.clear(); 925 } removeAll(Collection<?> collection)926 public boolean removeAll(Collection<?> collection) { 927 synchronized (Hashtable.this) { 928 return super.removeAll(collection); 929 } 930 } retainAll(Collection<?> collection)931 public boolean retainAll(Collection<?> collection) { 932 synchronized (Hashtable.this) { 933 return super.retainAll(collection); 934 } 935 } containsAll(Collection<?> collection)936 public boolean containsAll(Collection<?> collection) { 937 synchronized (Hashtable.this) { 938 return super.containsAll(collection); 939 } 940 } equals(Object object)941 public boolean equals(Object object) { 942 synchronized (Hashtable.this) { 943 return super.equals(object); 944 } 945 } hashCode()946 public int hashCode() { 947 synchronized (Hashtable.this) { 948 return super.hashCode(); 949 } 950 } toString()951 public String toString() { 952 synchronized (Hashtable.this) { 953 return super.toString(); 954 } 955 } toArray()956 public Object[] toArray() { 957 synchronized (Hashtable.this) { 958 return super.toArray(); 959 } 960 } toArray(T[] a)961 public <T> T[] toArray(T[] a) { 962 synchronized (Hashtable.this) { 963 return super.toArray(a); 964 } 965 } 966 } 967 968 private final class Values extends AbstractCollection<V> { iterator()969 public Iterator<V> iterator() { 970 return new ValueIterator(); 971 } size()972 public int size() { 973 return Hashtable.this.size(); 974 } contains(Object o)975 public boolean contains(Object o) { 976 return containsValue(o); 977 } clear()978 public void clear() { 979 Hashtable.this.clear(); 980 } containsAll(Collection<?> collection)981 public boolean containsAll(Collection<?> collection) { 982 synchronized (Hashtable.this) { 983 return super.containsAll(collection); 984 } 985 } toString()986 public String toString() { 987 synchronized (Hashtable.this) { 988 return super.toString(); 989 } 990 } toArray()991 public Object[] toArray() { 992 synchronized (Hashtable.this) { 993 return super.toArray(); 994 } 995 } toArray(T[] a)996 public <T> T[] toArray(T[] a) { 997 synchronized (Hashtable.this) { 998 return super.toArray(a); 999 } 1000 } 1001 } 1002 1003 private final class EntrySet extends AbstractSet<Entry<K, V>> { iterator()1004 public Iterator<Entry<K, V>> iterator() { 1005 return new EntryIterator(); 1006 } contains(Object o)1007 public boolean contains(Object o) { 1008 if (!(o instanceof Entry)) 1009 return false; 1010 Entry<?, ?> e = (Entry<?, ?>) o; 1011 return containsMapping(e.getKey(), e.getValue()); 1012 } remove(Object o)1013 public boolean remove(Object o) { 1014 if (!(o instanceof Entry)) 1015 return false; 1016 Entry<?, ?> e = (Entry<?, ?>)o; 1017 return removeMapping(e.getKey(), e.getValue()); 1018 } size()1019 public int size() { 1020 return Hashtable.this.size(); 1021 } clear()1022 public void clear() { 1023 Hashtable.this.clear(); 1024 } removeAll(Collection<?> collection)1025 public boolean removeAll(Collection<?> collection) { 1026 synchronized (Hashtable.this) { 1027 return super.removeAll(collection); 1028 } 1029 } retainAll(Collection<?> collection)1030 public boolean retainAll(Collection<?> collection) { 1031 synchronized (Hashtable.this) { 1032 return super.retainAll(collection); 1033 } 1034 } containsAll(Collection<?> collection)1035 public boolean containsAll(Collection<?> collection) { 1036 synchronized (Hashtable.this) { 1037 return super.containsAll(collection); 1038 } 1039 } equals(Object object)1040 public boolean equals(Object object) { 1041 synchronized (Hashtable.this) { 1042 return super.equals(object); 1043 } 1044 } hashCode()1045 public int hashCode() { 1046 return Hashtable.this.hashCode(); 1047 } toString()1048 public String toString() { 1049 synchronized (Hashtable.this) { 1050 return super.toString(); 1051 } 1052 } toArray()1053 public Object[] toArray() { 1054 synchronized (Hashtable.this) { 1055 return super.toArray(); 1056 } 1057 } toArray(T[] a)1058 public <T> T[] toArray(T[] a) { 1059 synchronized (Hashtable.this) { 1060 return super.toArray(a); 1061 } 1062 } 1063 } 1064 1065 /** 1066 * Applies a supplemental hash function to a given hashCode, which defends 1067 * against poor quality hash functions. This is critical because Hashtable 1068 * uses power-of-two length hash tables, that otherwise encounter collisions 1069 * for hashCodes that do not differ in lower or upper bits. 1070 */ secondaryHash(int h)1071 private static int secondaryHash(int h) { 1072 // Doug Lea's supplemental hash function 1073 h ^= (h >>> 20) ^ (h >>> 12); 1074 return h ^ (h >>> 7) ^ (h >>> 4); 1075 } 1076 1077 /** 1078 * Returns the smallest power of two >= its argument, with several caveats: 1079 * If the argument is negative but not Integer.MIN_VALUE, the method returns 1080 * zero. If the argument is > 2^30 or equal to Integer.MIN_VALUE, the method 1081 * returns Integer.MIN_VALUE. If the argument is zero, the method returns 1082 * zero. 1083 */ roundUpToPowerOfTwo(int i)1084 private static int roundUpToPowerOfTwo(int i) { 1085 i--; // If input is a power of two, shift its high-order bit right 1086 1087 // "Smear" the high-order bit all the way to the right 1088 i |= i >>> 1; 1089 i |= i >>> 2; 1090 i |= i >>> 4; 1091 i |= i >>> 8; 1092 i |= i >>> 16; 1093 1094 return i + 1; 1095 } 1096 1097 private static final long serialVersionUID = 1421746759512286392L; 1098 1099 /** 1100 * Serializable fields. 1101 * 1102 * @serialField loadFactor float 1103 * load factor for this Hashtable 1104 */ 1105 private static final ObjectStreamField[] serialPersistentFields = { 1106 new ObjectStreamField("threshold", Integer.TYPE), 1107 new ObjectStreamField("loadFactor", Float.TYPE) 1108 }; 1109 writeObject(ObjectOutputStream stream)1110 private synchronized void writeObject(ObjectOutputStream stream) 1111 throws IOException { 1112 // Emulate loadFactor field for other implementations to read 1113 ObjectOutputStream.PutField fields = stream.putFields(); 1114 fields.put("threshold", (int) (DEFAULT_LOAD_FACTOR * table.length)); 1115 fields.put("loadFactor", DEFAULT_LOAD_FACTOR); 1116 stream.writeFields(); 1117 1118 stream.writeInt(table.length); // Capacity 1119 stream.writeInt(size); 1120 for (Entry<K, V> e : entrySet()) { 1121 stream.writeObject(e.getKey()); 1122 stream.writeObject(e.getValue()); 1123 } 1124 } 1125 readObject(ObjectInputStream stream)1126 private void readObject(ObjectInputStream stream) throws IOException, 1127 ClassNotFoundException { 1128 stream.defaultReadObject(); 1129 int capacity = stream.readInt(); 1130 if (capacity < 0) { 1131 throw new InvalidObjectException("Capacity: " + capacity); 1132 } 1133 if (capacity < MINIMUM_CAPACITY) { 1134 capacity = MINIMUM_CAPACITY; 1135 } else if (capacity > MAXIMUM_CAPACITY) { 1136 capacity = MAXIMUM_CAPACITY; 1137 } else { 1138 capacity = roundUpToPowerOfTwo(capacity); 1139 } 1140 makeTable(capacity); 1141 1142 int size = stream.readInt(); 1143 if (size < 0) { 1144 throw new InvalidObjectException("Size: " + size); 1145 } 1146 1147 for (int i = 0; i < size; i++) { 1148 @SuppressWarnings("unchecked") K key = (K) stream.readObject(); 1149 @SuppressWarnings("unchecked") V val = (V) stream.readObject(); 1150 constructorPut(key, val); 1151 } 1152 } 1153 } 1154