public void remove() {
      if (!iterator) throw new UnsupportedOperationException();
      if (lastReturned == null) throw new IllegalStateException("Hashtable Enumerator");
      if (modCount != expectedModCount) throw new ConcurrentModificationException();

      synchronized (Hashtable.this) {
        Entry<?, ?>[] tab = Hashtable.this.table;
        int index = (lastReturned.hash & 0x7FFFFFFF) % tab.length;

        @SuppressWarnings("unchecked")
        Entry<K, V> e = (Entry<K, V>) tab[index];
        for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
          if (e == lastReturned) {
            if (prev == null) tab[index] = e.next;
            else prev.next = e.next;
            expectedModCount++;
            lastReturned = null;
            Hashtable.this.modCount++;
            Hashtable.this.count--;
            return;
          }
        }
        throw new ConcurrentModificationException();
      }
    }
  /**
   * {@inheritDoc}
   *
   * <p>This method will, on a best-effort basis, throw a {@link
   * java.util.ConcurrentModificationException} if the remapping function modified this map during
   * computation.
   *
   * @throws ConcurrentModificationException if it is detected that the remapping function modified
   *     this map
   */
  @Override
  public synchronized V computeIfPresent(
      K key, BiFunction<? super K, ? super V, ? extends V> remappingFunction) {
    Objects.requireNonNull(remappingFunction);

    Entry<?, ?> tab[] = table;
    int hash = key.hashCode();
    int index = (hash & 0x7FFFFFFF) % tab.length;
    @SuppressWarnings("unchecked")
    Entry<K, V> e = (Entry<K, V>) tab[index];
    for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
      if (e.hash == hash && e.key.equals(key)) {
        int mc = modCount;
        V newValue = remappingFunction.apply(key, e.value);
        if (mc != modCount) {
          throw new ConcurrentModificationException();
        }
        if (newValue == null) {
          if (prev != null) {
            prev.next = e.next;
          } else {
            tab[index] = e.next;
          }
          modCount = mc + 1;
          count--;
        } else {
          e.value = newValue;
        }
        return newValue;
      }
    }
    return null;
  }
  /**
   * Increases the capacity of and internally reorganizes this hashtable, in order to accommodate
   * and access its entries more efficiently. This method is called automatically when the number of
   * keys in the hashtable exceeds this hashtable's capacity and load factor.
   */
  @SuppressWarnings("unchecked")
  protected void rehash() {
    int oldCapacity = table.length;
    Entry<?, ?>[] oldMap = table;

    // overflow-conscious code
    int newCapacity = (oldCapacity << 1) + 1;
    if (newCapacity - MAX_ARRAY_SIZE > 0) {
      if (oldCapacity == MAX_ARRAY_SIZE)
        // Keep running with MAX_ARRAY_SIZE buckets
        return;
      newCapacity = MAX_ARRAY_SIZE;
    }
    Entry<?, ?>[] newMap = new Entry<?, ?>[newCapacity];

    modCount++;
    threshold = (int) Math.min(newCapacity * loadFactor, MAX_ARRAY_SIZE + 1);
    table = newMap;

    for (int i = oldCapacity; i-- > 0; ) {
      for (Entry<K, V> old = (Entry<K, V>) oldMap[i]; old != null; ) {
        Entry<K, V> e = old;
        old = old.next;

        int index = (e.hash & 0x7FFFFFFF) % newCapacity;
        e.next = (Entry<K, V>) newMap[index];
        newMap[index] = e;
      }
    }
  }
예제 #4
0
  /** Special version of remove for EntrySet using {@code Map.Entry.equals()} for matching. */
  final Entry<K, V> removeMapping(Object o) {
    if (!(o instanceof Map.Entry)) return null;

    Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
    Object key = entry.getKey();
    int hash = (key == null) ? 0 : hash(key);
    int i = indexFor(hash, table.length);
    Entry<K, V> prev = table[i];
    Entry<K, V> e = prev;

    while (e != null) {
      Entry<K, V> next = e.next;
      if (e.hash == hash && e.equals(entry)) {
        modCount++;
        size--;
        if (prev == e) table[i] = next;
        else prev.next = next;
        e.recordRemoval(this);
        return e;
      }
      prev = e;
      e = next;
    }

    return e;
  }
예제 #5
0
 /** Transfers all entries from current table to newTable. */
 void transfer(Entry[] newTable, boolean rehash) {
   int newCapacity = newTable.length;
   for (Entry<K, V> e : table) {
     while (null != e) {
       Entry<K, V> next = e.next;
       if (rehash) {
         e.hash = null == e.key ? 0 : hash(e.key);
       }
       int i = indexFor(e.hash, newCapacity);
       e.next = newTable[i];
       newTable[i] = e;
       e = next;
     }
   }
 }
예제 #6
0
 /**
  * Removes the key (and its corresponding value) from this hashtable. This method does nothing if
  * the key is not in the hashtable.
  *
  * @param key the key that needs to be removed
  * @return the value to which the key had been mapped in this hashtable, or <code>null</code> if
  *     the key did not have a mapping
  * @throws NullPointerException if the key is <code>null</code>
  */
 public synchronized V remove(Object key) {
   Entry tab[] = table;
   int hash = key.hashCode();
   int index = (hash & 0x7FFFFFFF) % tab.length;
   for (Entry<K, V> e = tab[index], prev = null; e != null; prev = e, e = e.next) {
     if ((e.hash == hash) && e.key.equals(key)) {
       modCount++;
       if (prev != null) {
         prev.next = e.next;
       } else {
         tab[index] = e.next;
       }
       count--;
       V oldValue = e.value;
       e.value = null;
       return oldValue;
     }
   }
   return null;
 }
예제 #7
0
    public boolean remove(Object o) {
      if (!(o instanceof Map.Entry)) return false;
      Map.Entry<K, V> entry = (Map.Entry<K, V>) o;
      K key = entry.getKey();
      Entry[] tab = table;
      int hash = key.hashCode();
      int index = (hash & 0x7FFFFFFF) % tab.length;

      for (Entry<K, V> e = tab[index], prev = null; e != null; prev = e, e = e.next) {
        if (e.hash == hash && e.equals(entry)) {
          modCount++;
          if (prev != null) prev.next = e.next;
          else tab[index] = e.next;

          count--;
          e.value = null;
          return true;
        }
      }
      return false;
    }
 /**
  * Removes the key (and its corresponding value) from this hashtable. This method does nothing if
  * the key is not in the hashtable.
  *
  * @param key the key that needs to be removed
  * @return the value to which the key had been mapped in this hashtable, or {@code null} if the
  *     key did not have a mapping
  * @throws NullPointerException if the key is {@code null}
  */
 public synchronized V remove(Object key) {
   Entry<?, ?> tab[] = table;
   int hash = key.hashCode();
   int index = (hash & 0x7FFFFFFF) % tab.length;
   @SuppressWarnings("unchecked")
   Entry<K, V> e = (Entry<K, V>) tab[index];
   for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
     if ((e.hash == hash) && e.key.equals(key)) {
       if (prev != null) {
         prev.next = e.next;
       } else {
         tab[index] = e.next;
       }
       modCount++;
       count--;
       V oldValue = e.value;
       e.value = null;
       return oldValue;
     }
   }
   return null;
 }
    public boolean remove(Object o) {
      if (!(o instanceof Map.Entry)) return false;
      Map.Entry<?, ?> entry = (Map.Entry<?, ?>) o;
      Object key = entry.getKey();
      Entry<?, ?>[] tab = table;
      int hash = key.hashCode();
      int index = (hash & 0x7FFFFFFF) % tab.length;

      @SuppressWarnings("unchecked")
      Entry<K, V> e = (Entry<K, V>) tab[index];
      for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
        if (e.hash == hash && e.equals(entry)) {
          if (prev != null) prev.next = e.next;
          else tab[index] = e.next;

          e.value = null; // clear for gc.
          modCount++;
          count--;
          return true;
        }
      }
      return false;
    }
예제 #10
0
  /**
   * Removes and returns the entry associated with the specified key in the HashMap. Returns null if
   * the HashMap contains no mapping for this key.
   */
  final Entry<K, V> removeEntryForKey(Object key) {
    int hash = (key == null) ? 0 : hash(key);
    int i = indexFor(hash, table.length);
    Entry<K, V> prev = table[i];
    Entry<K, V> e = prev;

    while (e != null) {
      Entry<K, V> next = e.next;
      Object k;
      if (e.hash == hash && ((k = e.key) == key || (key != null && key.equals(k)))) {
        modCount++;
        size--;
        if (prev == e) table[i] = next;
        else prev.next = next;
        e.recordRemoval(this);
        return e;
      }
      prev = e;
      e = next;
    }

    return e;
  }
  @Override
  public synchronized boolean remove(Object key, Object value) {
    Objects.requireNonNull(value);

    Entry<?, ?> tab[] = table;
    int hash = key.hashCode();
    int index = (hash & 0x7FFFFFFF) % tab.length;
    @SuppressWarnings("unchecked")
    Entry<K, V> e = (Entry<K, V>) tab[index];
    for (Entry<K, V> prev = null; e != null; prev = e, e = e.next) {
      if ((e.hash == hash) && e.key.equals(key) && e.value.equals(value)) {
        if (prev != null) {
          prev.next = e.next;
        } else {
          tab[index] = e.next;
        }
        e.value = null; // clear for gc
        modCount++;
        count--;
        return true;
      }
    }
    return false;
  }