438 int index = (hash & 0x7FFFFFFF) % tab.length;
439 for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
440 if ((e.hash == hash) && e.key.equals(key)) {
441 V old = e.value;
442 e.value = value;
443 return old;
444 }
445 }
446
447 modCount++;
448 if (count >= threshold) {
449 // Rehash the table if the threshold is exceeded
450 rehash();
451
452 tab = table;
453 index = (hash & 0x7FFFFFFF) % tab.length;
454 }
455
456 // Creates the new entry.
457 Entry<K,V> e = tab[index];
458 tab[index] = new Entry<K,V>(hash, key, value, e);
459 count++;
460 return null;
461 }
462
463 /**
464 * Removes the key (and its corresponding value) from this
465 * hashtable. This method does nothing if the key is not in the hashtable.
466 *
467 * @param key the key that needs to be removed
468 * @return the value to which the key had been mapped in this hashtable,
469 * or <code>null</code> if the key did not have a mapping
470 * @throws NullPointerException if the key is <code>null</code>
471 */
472 public synchronized V remove(Object key) {
473 Entry tab[] = table;
474 int hash = key.hashCode();
475 int index = (hash & 0x7FFFFFFF) % tab.length;
476 for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
477 if ((e.hash == hash) && e.key.equals(key)) {
478 modCount++;
562 sb.append('{');
563 for (int i = 0; ; i++) {
564 Map.Entry<K,V> e = it.next();
565 K key = e.getKey();
566 V value = e.getValue();
567 sb.append(key == this ? "(this Map)" : key.toString());
568 sb.append('=');
569 sb.append(value == this ? "(this Map)" : value.toString());
570
571 if (i == max)
572 return sb.append('}').toString();
573 sb.append(", ");
574 }
575 }
576
577
578 private <T> Enumeration<T> getEnumeration(int type) {
579 if (count == 0) {
580 return Collections.emptyEnumeration();
581 } else {
582 return new Enumerator<T>(type, false);
583 }
584 }
585
586 private <T> Iterator<T> getIterator(int type) {
587 if (count == 0) {
588 return Collections.emptyIterator();
589 } else {
590 return new Enumerator<T>(type, true);
591 }
592 }
593
594 // Views
595
596 /**
597 * Each of these fields are initialized to contain an instance of the
598 * appropriate view the first time this view is requested. The views are
599 * stateless, so there's no reason to create more than one of each.
600 */
601 private transient volatile Set<K> keySet = null;
602 private transient volatile Set<Map.Entry<K,V>> entrySet = null;
603 private transient volatile Collection<V> values = null;
604
605 /**
606 * Returns a {@link Set} view of the keys contained in this map.
607 * The set is backed by the map, so changes to the map are
608 * reflected in the set, and vice-versa. If the map is modified
609 * while an iteration over the set is in progress (except through
610 * the iterator's own <tt>remove</tt> operation), the results of
912 * because we are creating a new instance. Also, no return value
913 * is needed.
914 */
915 private void reconstitutionPut(Entry[] tab, K key, V value)
916 throws StreamCorruptedException
917 {
918 if (value == null) {
919 throw new java.io.StreamCorruptedException();
920 }
921 // Makes sure the key is not already in the hashtable.
922 // This should not happen in deserialized version.
923 int hash = key.hashCode();
924 int index = (hash & 0x7FFFFFFF) % tab.length;
925 for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
926 if ((e.hash == hash) && e.key.equals(key)) {
927 throw new java.io.StreamCorruptedException();
928 }
929 }
930 // Creates the new entry.
931 Entry<K,V> e = tab[index];
932 tab[index] = new Entry<K,V>(hash, key, value, e);
933 count++;
934 }
935
936 /**
937 * Hashtable collision list.
938 */
939 private static class Entry<K,V> implements Map.Entry<K,V> {
940 int hash;
941 K key;
942 V value;
943 Entry<K,V> next;
944
945 protected Entry(int hash, K key, V value, Entry<K,V> next) {
946 this.hash = hash;
947 this.key = key;
948 this.value = value;
949 this.next = next;
950 }
951
952 protected Object clone() {
953 return new Entry<K,V>(hash, key, value,
954 (next==null ? null : (Entry<K,V>) next.clone()));
955 }
956
957 // Map.Entry Ops
958
959 public K getKey() {
960 return key;
961 }
962
963 public V getValue() {
964 return value;
965 }
966
967 public V setValue(V value) {
968 if (value == null)
969 throw new NullPointerException();
970
971 V oldValue = this.value;
972 this.value = value;
973 return oldValue;
|
438 int index = (hash & 0x7FFFFFFF) % tab.length;
439 for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
440 if ((e.hash == hash) && e.key.equals(key)) {
441 V old = e.value;
442 e.value = value;
443 return old;
444 }
445 }
446
447 modCount++;
448 if (count >= threshold) {
449 // Rehash the table if the threshold is exceeded
450 rehash();
451
452 tab = table;
453 index = (hash & 0x7FFFFFFF) % tab.length;
454 }
455
456 // Creates the new entry.
457 Entry<K,V> e = tab[index];
458 tab[index] = new Entry<>(hash, key, value, e);
459 count++;
460 return null;
461 }
462
463 /**
464 * Removes the key (and its corresponding value) from this
465 * hashtable. This method does nothing if the key is not in the hashtable.
466 *
467 * @param key the key that needs to be removed
468 * @return the value to which the key had been mapped in this hashtable,
469 * or <code>null</code> if the key did not have a mapping
470 * @throws NullPointerException if the key is <code>null</code>
471 */
472 public synchronized V remove(Object key) {
473 Entry tab[] = table;
474 int hash = key.hashCode();
475 int index = (hash & 0x7FFFFFFF) % tab.length;
476 for (Entry<K,V> e = tab[index], prev = null ; e != null ; prev = e, e = e.next) {
477 if ((e.hash == hash) && e.key.equals(key)) {
478 modCount++;
562 sb.append('{');
563 for (int i = 0; ; i++) {
564 Map.Entry<K,V> e = it.next();
565 K key = e.getKey();
566 V value = e.getValue();
567 sb.append(key == this ? "(this Map)" : key.toString());
568 sb.append('=');
569 sb.append(value == this ? "(this Map)" : value.toString());
570
571 if (i == max)
572 return sb.append('}').toString();
573 sb.append(", ");
574 }
575 }
576
577
578 private <T> Enumeration<T> getEnumeration(int type) {
579 if (count == 0) {
580 return Collections.emptyEnumeration();
581 } else {
582 return new Enumerator<>(type, false);
583 }
584 }
585
586 private <T> Iterator<T> getIterator(int type) {
587 if (count == 0) {
588 return Collections.emptyIterator();
589 } else {
590 return new Enumerator<>(type, true);
591 }
592 }
593
594 // Views
595
596 /**
597 * Each of these fields are initialized to contain an instance of the
598 * appropriate view the first time this view is requested. The views are
599 * stateless, so there's no reason to create more than one of each.
600 */
601 private transient volatile Set<K> keySet = null;
602 private transient volatile Set<Map.Entry<K,V>> entrySet = null;
603 private transient volatile Collection<V> values = null;
604
605 /**
606 * Returns a {@link Set} view of the keys contained in this map.
607 * The set is backed by the map, so changes to the map are
608 * reflected in the set, and vice-versa. If the map is modified
609 * while an iteration over the set is in progress (except through
610 * the iterator's own <tt>remove</tt> operation), the results of
912 * because we are creating a new instance. Also, no return value
913 * is needed.
914 */
915 private void reconstitutionPut(Entry[] tab, K key, V value)
916 throws StreamCorruptedException
917 {
918 if (value == null) {
919 throw new java.io.StreamCorruptedException();
920 }
921 // Makes sure the key is not already in the hashtable.
922 // This should not happen in deserialized version.
923 int hash = key.hashCode();
924 int index = (hash & 0x7FFFFFFF) % tab.length;
925 for (Entry<K,V> e = tab[index] ; e != null ; e = e.next) {
926 if ((e.hash == hash) && e.key.equals(key)) {
927 throw new java.io.StreamCorruptedException();
928 }
929 }
930 // Creates the new entry.
931 Entry<K,V> e = tab[index];
932 tab[index] = new Entry<>(hash, key, value, e);
933 count++;
934 }
935
936 /**
937 * Hashtable collision list.
938 */
939 private static class Entry<K,V> implements Map.Entry<K,V> {
940 int hash;
941 K key;
942 V value;
943 Entry<K,V> next;
944
945 protected Entry(int hash, K key, V value, Entry<K,V> next) {
946 this.hash = hash;
947 this.key = key;
948 this.value = value;
949 this.next = next;
950 }
951
952 protected Object clone() {
953 return new Entry<>(hash, key, value,
954 (next==null ? null : (Entry<K,V>) next.clone()));
955 }
956
957 // Map.Entry Ops
958
959 public K getKey() {
960 return key;
961 }
962
963 public V getValue() {
964 return value;
965 }
966
967 public V setValue(V value) {
968 if (value == null)
969 throw new NullPointerException();
970
971 V oldValue = this.value;
972 this.value = value;
973 return oldValue;
|