OSDN Git Service

Merged gcj-eclipse branch to trunk.
[pf3gnuchains/gcc-fork.git] / libjava / classpath / java / util / Hashtable.java
index 4c00d18..2e265a4 100644 (file)
@@ -100,8 +100,8 @@ import java.io.Serializable;
  * @since 1.0
  * @status updated to 1.4
  */
-public class Hashtable extends Dictionary
-  implements Map, Cloneable, Serializable
+public class Hashtable<K, V> extends Dictionary<K, V>
+  implements Map<K, V>, Cloneable, Serializable
 {
   // WARNING: Hashtable is a CORE class in the bootstrap cycle. See the
   // comments in vm/reference/java/lang/Runtime for implications of this fact.
@@ -139,7 +139,7 @@ public class Hashtable extends Dictionary
    * Array containing the actual key-value mappings.
    */
   // Package visible for use by nested classes.
-  transient HashEntry[] buckets;
+  transient HashEntry<K, V>[] buckets;
 
   /**
    * Counts the number of modifications this Hashtable has undergone, used
@@ -157,34 +157,35 @@ public class Hashtable extends Dictionary
   /**
    * The cache for {@link #keySet()}.
    */
-  private transient Set keys;
+  private transient Set<K> keys;
 
   /**
    * The cache for {@link #values()}.
    */
-  private transient Collection values;
+  private transient Collection<V> values;
 
   /**
    * The cache for {@link #entrySet()}.
    */
-  private transient Set entries;
+  private transient Set<Map.Entry<K, V>> entries;
 
   /**
    * Class to represent an entry in the hash table. Holds a single key-value
    * pair. A Hashtable Entry is identical to a HashMap Entry, except that
    * `null' is not allowed for keys and values.
    */
-  private static final class HashEntry extends AbstractMap.BasicMapEntry
+  private static final class HashEntry<K, V>
+    extends AbstractMap.SimpleEntry<K, V>
   {
     /** The next entry in the linked list. */
-    HashEntry next;
+    HashEntry<K, V> next;
 
     /**
      * Simple constructor.
      * @param key the key, already guaranteed non-null
      * @param value the value, already guaranteed non-null
      */
-    HashEntry(Object key, Object value)
+    HashEntry(K key, V value)
     {
       super(key, value);
     }
@@ -195,7 +196,7 @@ public class Hashtable extends Dictionary
      * @return the prior value
      * @throws NullPointerException if <code>newVal</code> is null
      */
-    public Object setValue(Object newVal)
+    public V setValue(V newVal)
     {
       if (newVal == null)
         throw new NullPointerException();
@@ -226,7 +227,7 @@ public class Hashtable extends Dictionary
    *         to or from `null'.
    * @since 1.2
    */
-  public Hashtable(Map m)
+  public Hashtable(Map<? extends K, ? extends V> m)
   {
     this(Math.max(m.size() * 2, DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR);
     putAll(m);
@@ -263,7 +264,7 @@ public class Hashtable extends Dictionary
 
     if (initialCapacity == 0)
       initialCapacity = 1;
-    buckets = new HashEntry[initialCapacity];
+    buckets = (HashEntry<K, V>[]) new HashEntry[initialCapacity];
     this.loadFactor = loadFactor;
     threshold = (int) (initialCapacity * loadFactor);
   }
@@ -295,7 +296,7 @@ public class Hashtable extends Dictionary
    * @see #elements()
    * @see #keySet()
    */
-  public Enumeration keys()
+  public Enumeration<K> keys()
   {
     return new KeyEnumerator();
   }
@@ -309,7 +310,7 @@ public class Hashtable extends Dictionary
    * @see #keys()
    * @see #values()
    */
-  public Enumeration elements()
+  public Enumeration<V> elements()
   {
     return new ValueEnumerator();
   }
@@ -333,7 +334,7 @@ public class Hashtable extends Dictionary
 
     for (int i = buckets.length - 1; i >= 0; i--)
       {
-        HashEntry e = buckets[i];
+        HashEntry<K, V> e = buckets[i];
         while (e != null)
           {
             if (e.value.equals(value))
@@ -341,7 +342,7 @@ public class Hashtable extends Dictionary
             e = e.next;
           }
       }
+
     return false;  
   }
 
@@ -376,7 +377,7 @@ public class Hashtable extends Dictionary
   public synchronized boolean containsKey(Object key)
   {
     int idx = hash(key);
-    HashEntry e = buckets[idx];
+    HashEntry<K, V> e = buckets[idx];
     while (e != null)
       {
         if (e.key.equals(key))
@@ -396,10 +397,10 @@ public class Hashtable extends Dictionary
    * @see #put(Object, Object)
    * @see #containsKey(Object)
    */
-  public synchronized Object get(Object key)
+  public synchronized V get(Object key)
   {
     int idx = hash(key);
-    HashEntry e = buckets[idx];
+    HashEntry<K, V> e = buckets[idx];
     while (e != null)
       {
         if (e.key.equals(key))
@@ -421,10 +422,10 @@ public class Hashtable extends Dictionary
    * @see #get(Object)
    * @see Object#equals(Object)
    */
-  public synchronized Object put(Object key, Object value)
+  public synchronized V put(K key, V value)
   {
     int idx = hash(key);
-    HashEntry e = buckets[idx];
+    HashEntry<K, V> e = buckets[idx];
 
     // Check if value is null since it is not permitted.
     if (value == null)
@@ -435,7 +436,7 @@ public class Hashtable extends Dictionary
         if (e.key.equals(key))
           {
             // Bypass e.setValue, since we already know value is non-null.
-            Object r = e.value;
+            V r = e.value;
             e.value = value;
             return r;
           }
@@ -454,7 +455,7 @@ public class Hashtable extends Dictionary
         idx = hash(key);
       }
 
-    e = new HashEntry(key, value);
+    e = new HashEntry<K, V>(key, value);
 
     e.next = buckets[idx];
     buckets[idx] = e;
@@ -470,11 +471,11 @@ public class Hashtable extends Dictionary
    * @param key the key used to locate the value to remove
    * @return whatever the key mapped to, if present
    */
-  public synchronized Object remove(Object key)
+  public synchronized V remove(Object key)
   {
     int idx = hash(key);
-    HashEntry e = buckets[idx];
-    HashEntry last = null;
+    HashEntry<K, V> e = buckets[idx];
+    HashEntry<K, V> last = null;
 
     while (e != null)
       {
@@ -502,17 +503,19 @@ public class Hashtable extends Dictionary
    * @param m the map to be hashed into this
    * @throws NullPointerException if m is null, or contains null keys or values
    */
-  public synchronized void putAll(Map m)
+  public synchronized void putAll(Map<? extends K, ? extends V> m)
   {
-    Iterator itr = m.entrySet().iterator();
+    Map<K,V> addMap;
+    
+    addMap = (Map<K,V>) m;
 
-    while (itr.hasNext())
+    for (Map.Entry<K,V> e : addMap.entrySet())
       {
-        Map.Entry e = (Map.Entry) itr.next();
         // Optimize in case the Entry is one of our own.
-        if (e instanceof AbstractMap.BasicMapEntry)
+        if (e instanceof AbstractMap.SimpleEntry)
           {
-            AbstractMap.BasicMapEntry entry = (AbstractMap.BasicMapEntry) e;
+            AbstractMap.SimpleEntry<? extends K, ? extends V> entry
+             = (AbstractMap.SimpleEntry<? extends K, ? extends V>) e;
             put(entry.key, entry.value);
           }
         else
@@ -543,16 +546,16 @@ public class Hashtable extends Dictionary
    */
   public synchronized Object clone()
   {
-    Hashtable copy = null;
+    Hashtable<K, V> copy = null;
     try
       {
-        copy = (Hashtable) super.clone();
+        copy = (Hashtable<K, V>) super.clone();
       }
     catch (CloneNotSupportedException x)
       {
         // This is impossible.
       }
-    copy.buckets = new HashEntry[buckets.length];
+    copy.buckets = (HashEntry<K, V>[]) new HashEntry[buckets.length];
     copy.putAllInternal(this);
     // Clear the caches.
     copy.keys = null;
@@ -576,7 +579,7 @@ public class Hashtable extends Dictionary
     // Since we are already synchronized, and entrySet().iterator()
     // would repeatedly re-lock/release the monitor, we directly use the
     // unsynchronized EntryIterator instead.
-    Iterator entries = new EntryIterator();
+    Iterator<Map.Entry<K, V>> entries = new EntryIterator();
     StringBuffer r = new StringBuffer("{");
     for (int pos = size; pos > 0; pos--)
       {
@@ -603,20 +606,20 @@ public class Hashtable extends Dictionary
    * @see #entrySet()
    * @since 1.2
    */
-  public Set keySet()
+  public Set<K> keySet()
   {
     if (keys == null)
       {
         // Create a synchronized AbstractSet with custom implementations of
         // those methods that can be overridden easily and efficiently.
-        Set r = new AbstractSet()
+        Set<K> r = new AbstractSet<K>()
         {
           public int size()
           {
             return size;
           }
 
-          public Iterator iterator()
+          public Iterator<K> iterator()
           {
             return new KeyIterator();
           }
@@ -640,7 +643,7 @@ public class Hashtable extends Dictionary
         };
         // We must specify the correct object to synchronize upon, hence the
         // use of a non-public API
-        keys = new Collections.SynchronizedSet(this, r);
+        keys = new Collections.SynchronizedSet<K>(this, r);
       }
     return keys;
   }
@@ -661,20 +664,20 @@ public class Hashtable extends Dictionary
    * @see #entrySet()
    * @since 1.2
    */
-  public Collection values()
+  public Collection<V> values()
   {
     if (values == null)
       {
         // We don't bother overriding many of the optional methods, as doing so
         // wouldn't provide any significant performance advantage.
-        Collection r = new AbstractCollection()
+        Collection<V> r = new AbstractCollection<V>()
         {
           public int size()
           {
             return size;
           }
 
-          public Iterator iterator()
+          public Iterator<V> iterator()
           {
             return new ValueIterator();
           }
@@ -686,7 +689,7 @@ public class Hashtable extends Dictionary
         };
         // We must specify the correct object to synchronize upon, hence the
         // use of a non-public API
-        values = new Collections.SynchronizedCollection(this, r);
+        values = new Collections.SynchronizedCollection<V>(this, r);
       }
     return values;
   }
@@ -713,20 +716,20 @@ public class Hashtable extends Dictionary
    * @see Map.Entry
    * @since 1.2
    */
-  public Set entrySet()
+  public Set<Map.Entry<K, V>> entrySet()
   {
     if (entries == null)
       {
         // Create an AbstractSet with custom implementations of those methods
         // that can be overridden easily and efficiently.
-        Set r = new AbstractSet()
+        Set<Map.Entry<K, V>> r = new AbstractSet<Map.Entry<K, V>>()
         {
           public int size()
           {
             return size;
           }
 
-          public Iterator iterator()
+          public Iterator<Map.Entry<K, V>> iterator()
           {
             return new EntryIterator();
           }
@@ -743,7 +746,7 @@ public class Hashtable extends Dictionary
 
           public boolean remove(Object o)
           {
-            HashEntry e = getEntry(o);
+            HashEntry<K, V> e = getEntry(o);
             if (e != null)
               {
                 Hashtable.this.remove(e.key);
@@ -754,7 +757,7 @@ public class Hashtable extends Dictionary
         };
         // We must specify the correct object to synchronize upon, hence the
         // use of a non-public API
-        entries = new Collections.SynchronizedSet(this, r);
+        entries = new Collections.SynchronizedSet<Map.Entry<K, V>>(this, r);
       }
     return entries;
   }
@@ -772,7 +775,7 @@ public class Hashtable extends Dictionary
    */
   public boolean equals(Object o)
   {
-    // no need to synchronize, entrySet().equals() does that
+    // no need to synchronize, entrySet().equals() does that.
     if (o == this)
       return true;
     if (!(o instanceof Map))
@@ -793,7 +796,7 @@ public class Hashtable extends Dictionary
     // Since we are already synchronized, and entrySet().iterator()
     // would repeatedly re-lock/release the monitor, we directly use the
     // unsynchronized EntryIterator instead.
-    Iterator itr = new EntryIterator();
+    Iterator<Map.Entry<K, V>> itr = new EntryIterator();
     int hashcode = 0;
     for (int pos = size; pos > 0; pos--)
       hashcode += itr.next().hashCode();
@@ -826,16 +829,16 @@ public class Hashtable extends Dictionary
    * @see #entrySet()
    */
   // Package visible, for use in nested classes.
-  HashEntry getEntry(Object o)
+  HashEntry<K, V> getEntry(Object o)
   {
     if (! (o instanceof Map.Entry))
       return null;
-    Object key = ((Map.Entry) o).getKey();
+    K key = ((Map.Entry<K, V>) o).getKey();
     if (key == null)
       return null;
 
     int idx = hash(key);
-    HashEntry e = buckets[idx];
+    HashEntry<K, V> e = buckets[idx];
     while (e != null)
       {
         if (e.equals(o))
@@ -852,18 +855,19 @@ public class Hashtable extends Dictionary
    *
    * @param m the map to initialize this from
    */
-  void putAllInternal(Map m)
+  void putAllInternal(Map<? extends K, ? extends V> m)
   {
-    Iterator itr = m.entrySet().iterator();
+    Map<K,V> addMap;
+
+    addMap = (Map<K,V>) m;
     size = 0;
 
-    while (itr.hasNext())
+    for (Map.Entry<K,V> e : addMap.entrySet())
       {
         size++;
-       Map.Entry e = (Map.Entry) itr.next();
-       Object key = e.getKey();
+       K key = e.getKey();
        int idx = hash(key);
-       HashEntry he = new HashEntry(key, e.getValue());
+       HashEntry<K, V> he = new HashEntry<K, V>(key, e.getValue());
        he.next = buckets[idx];
        buckets[idx] = he;
       }
@@ -882,19 +886,19 @@ public class Hashtable extends Dictionary
    */
   protected void rehash()
   {
-    HashEntry[] oldBuckets = buckets;
+    HashEntry<K, V>[] oldBuckets = buckets;
 
     int newcapacity = (buckets.length * 2) + 1;
     threshold = (int) (newcapacity * loadFactor);
-    buckets = new HashEntry[newcapacity];
+    buckets = (HashEntry<K, V>[]) new HashEntry[newcapacity];
 
     for (int i = oldBuckets.length - 1; i >= 0; i--)
       {
-        HashEntry e = oldBuckets[i];
+        HashEntry<K, V> e = oldBuckets[i];
         while (e != null)
           {
             int idx = hash(e.key);
-            HashEntry dest = buckets[idx];
+            HashEntry<K, V> dest = buckets[idx];
 
             if (dest != null)
               {
@@ -911,7 +915,7 @@ public class Hashtable extends Dictionary
                 buckets[idx] = e;
               }
 
-            HashEntry next = e.next;
+            HashEntry<K, V> next = e.next;
             e.next = null;
             e = next;
           }
@@ -939,10 +943,10 @@ public class Hashtable extends Dictionary
     // Since we are already synchronized, and entrySet().iterator()
     // would repeatedly re-lock/release the monitor, we directly use the
     // unsynchronized EntryIterator instead.
-    Iterator it = new EntryIterator();
+    Iterator<Map.Entry<K, V>> it = new EntryIterator();
     while (it.hasNext())
       {
-        HashEntry entry = (HashEntry) it.next();
+        HashEntry<K, V> entry = (HashEntry<K, V>) it.next();
         s.writeObject(entry.key);
         s.writeObject(entry.value);
       }
@@ -966,13 +970,13 @@ public class Hashtable extends Dictionary
     s.defaultReadObject();
 
     // Read and use capacity.
-    buckets = new HashEntry[s.readInt()];
+    buckets = (HashEntry<K, V>[]) new HashEntry[s.readInt()];
     int len = s.readInt();
 
     // Read and use key/value pairs.
     // TODO: should we be defensive programmers, and check for illegal nulls?
     while (--len >= 0)
-      put(s.readObject(), s.readObject());
+      put((K) s.readObject(), (V) s.readObject());
   }
 
   /**
@@ -987,7 +991,8 @@ public class Hashtable extends Dictionary
    * @author Jon Zeppieri
    * @author Fridjof Siebert
    */
-  private class EntryIterator implements Iterator
+  private class EntryIterator 
+      implements Iterator<Entry<K,V>>
   {
     /**
      * The number of modifications to the backing Hashtable that we know about.
@@ -998,16 +1003,16 @@ public class Hashtable extends Dictionary
     /** Current index in the physical hash table. */
     int idx = buckets.length;
     /** The last Entry returned by a next() call. */
-    HashEntry last;
+    HashEntry<K, V> last;
     /**
      * The next entry that should be returned by next(). It is set to something
      * if we're iterating through a bucket that contains multiple linked
      * entries. It is null if next() needs to find a new bucket.
      */
-    HashEntry next;
+    HashEntry<K, V> next;
 
     /**
-     * Construct a new EtryIterator
+     * Construct a new EntryIterator
      */
     EntryIterator()
     {
@@ -1029,14 +1034,14 @@ public class Hashtable extends Dictionary
      * @throws ConcurrentModificationException if the hashtable was modified
      * @throws NoSuchElementException if there is none
      */
-    public Object next()
+    public Map.Entry<K,V> next()
     {
       if (knownMod != modCount)
         throw new ConcurrentModificationException();
       if (count == 0)
         throw new NoSuchElementException();
       count--;
-      HashEntry e = next;
+      HashEntry<K, V> e = next;
 
       while (e == null)
        if (idx <= 0)
@@ -1070,12 +1075,43 @@ public class Hashtable extends Dictionary
 
   /**
    * A class which implements the Iterator interface and is used for
-   * iterating over keys in Hashtables.
+   * iterating over keys in Hashtables.  This class uses an
+   * <code>EntryIterator</code> to obtain the keys of each entry.
    *
    * @author Fridtjof Siebert
+   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
    */
-  private class KeyIterator extends EntryIterator
+  private class KeyIterator 
+      implements Iterator<K>
   {
+
+    /**
+     * This entry iterator is used for most operations.  Only
+     * <code>next()</code> gives a different result, by returning just
+     * the key rather than the whole element.
+     */
+    private EntryIterator iterator;
+
+    /**
+     * Construct a new KeyIterator
+     */
+    KeyIterator()
+    {
+       iterator = new EntryIterator();
+    }
+
+
+    /**
+     * Returns true if the entry iterator has more elements.
+     *
+     * @return true if there are more elements
+     * @throws ConcurrentModificationException if the hashtable was modified
+     */
+    public boolean hasNext()
+    {
+       return iterator.hasNext();
+    }
+
     /**
      * Returns the next element in the Iterator's sequential view.
      *
@@ -1084,34 +1120,88 @@ public class Hashtable extends Dictionary
      * @throws ConcurrentModificationException if the hashtable was modified
      * @throws NoSuchElementException if there is none
      */
-    public Object next()
+    public K next()
     {
-      return ((HashEntry)super.next()).key;
+      return ((HashEntry<K,V>) iterator.next()).key;
     }
-  } // class KeyIterator
-
-
 
+    /**
+     * Removes the last element used by the <code>next()</code> method
+     * using the entry iterator.
+     *
+     * @throws ConcurrentModificationException if the hashtable was modified
+     * @throws IllegalStateException if called when there is no last element
+     */
+    public void remove()
+    {
+      iterator.remove();
+    }
+  } // class KeyIterator
   /**
    * A class which implements the Iterator interface and is used for
-   * iterating over values in Hashtables.
+   * iterating over values in Hashtables.  This class uses an
+   * <code>EntryIterator</code> to obtain the values of each entry.
    *
    * @author Fridtjof Siebert
+   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
    */
-  private class ValueIterator extends EntryIterator
+  private class ValueIterator
+      implements Iterator<V>
   {
+
     /**
-     * Returns the next element in the Iterator's sequential view.
+     * This entry iterator is used for most operations.  Only
+     * <code>next()</code> gives a different result, by returning just
+     * the value rather than the whole element.
+     */
+    private EntryIterator iterator;
+
+    /**
+     * Construct a new KeyIterator
+     */
+    ValueIterator()
+    {
+       iterator = new EntryIterator();
+    }
+
+
+    /**
+     * Returns true if the entry iterator has more elements.
      *
-     * @return the next element
+     * @return true if there are more elements
+     * @throws ConcurrentModificationException if the hashtable was modified
+     */
+    public boolean hasNext()
+    {
+       return iterator.hasNext();
+    }
+
+    /**
+     * Returns the value of the next element in the iterator's sequential view.
+     *
+     * @return the next value
      *
      * @throws ConcurrentModificationException if the hashtable was modified
      * @throws NoSuchElementException if there is none
      */
-    public Object next()
+    public V next()
+    {
+      return ((HashEntry<K,V>) iterator.next()).value;
+    }
+
+    /**
+     * Removes the last element used by the <code>next()</code> method
+     * using the entry iterator.
+     *
+     * @throws ConcurrentModificationException if the hashtable was modified
+     * @throws IllegalStateException if called when there is no last element
+     */
+    public void remove()
     {
-      return ((HashEntry)super.next()).value;
+      iterator.remove();
     }
+
   } // class ValueIterator
 
   /**
@@ -1128,7 +1218,8 @@ public class Hashtable extends Dictionary
    * @author Jon Zeppieri
    * @author Fridjof Siebert
    */
-  private class EntryEnumerator implements Enumeration
+  private class EntryEnumerator 
+      implements Enumeration<Entry<K,V>>
   {
     /** The number of elements remaining to be returned by next(). */
     int count = size;
@@ -1139,7 +1230,7 @@ public class Hashtable extends Dictionary
      * set if we are iterating through a bucket with multiple entries, or null
      * if we must look in the next bucket.
      */
-    HashEntry next;
+    HashEntry<K, V> next;
 
     /**
      * Construct the enumeration.
@@ -1163,12 +1254,12 @@ public class Hashtable extends Dictionary
      * @return the next element
      * @throws NoSuchElementException if there is none.
      */
-    public Object nextElement()
+    public Map.Entry<K,V> nextElement()
     {
       if (count == 0)
         throw new NoSuchElementException("Hashtable Enumerator");
       count--;
-      HashEntry e = next;
+      HashEntry<K, V> e = next;
 
       while (e == null)
         if (idx <= 0)
@@ -1195,18 +1286,47 @@ public class Hashtable extends Dictionary
    *
    * @author Jon Zeppieri
    * @author Fridjof Siebert
+   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
    */
-  private final class KeyEnumerator extends EntryEnumerator
+  private final class KeyEnumerator
+      implements Enumeration<K>
   {
     /**
+     * This entry enumerator is used for most operations.  Only
+     * <code>nextElement()</code> gives a different result, by returning just
+     * the key rather than the whole element.
+     */
+    private EntryEnumerator enumerator;
+
+    /**
+     * Construct a new KeyEnumerator
+     */
+    KeyEnumerator()
+    {
+      enumerator = new EntryEnumerator();
+    }
+
+
+    /**
+     * Returns true if the entry enumerator has more elements.
+     *
+     * @return true if there are more elements
+     * @throws ConcurrentModificationException if the hashtable was modified
+     */
+    public boolean hasMoreElements()
+    {
+       return enumerator.hasMoreElements();
+    }
+
+    /**
      * Returns the next element.
      * @return the next element
      * @throws NoSuchElementException if there is none.
      */
-    public Object nextElement()
+    public K nextElement()
     {
-      HashEntry entry = (HashEntry) super.nextElement();
-      Object retVal = null;
+      HashEntry<K,V> entry = (HashEntry<K,V>) enumerator.nextElement();
+      K retVal = null;
       if (entry != null)
         retVal = entry.key;
       return retVal;
@@ -1227,18 +1347,47 @@ public class Hashtable extends Dictionary
    *
    * @author Jon Zeppieri
    * @author Fridjof Siebert
+   * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
    */
-  private final class ValueEnumerator extends EntryEnumerator
+  private final class ValueEnumerator
+      implements Enumeration<V>
   {
     /**
+     * This entry enumerator is used for most operations.  Only
+     * <code>nextElement()</code> gives a different result, by returning just
+     * the value rather than the whole element.
+     */
+    private EntryEnumerator enumerator;
+
+    /**
+     * Construct a new ValueEnumerator
+     */
+    ValueEnumerator()
+    {
+      enumerator = new EntryEnumerator();
+    }
+
+
+    /**
+     * Returns true if the entry enumerator has more elements.
+     *
+     * @return true if there are more elements
+     * @throws ConcurrentModificationException if the hashtable was modified
+     */
+    public boolean hasMoreElements()
+    {
+       return enumerator.hasMoreElements();
+    }
+
+    /**
      * Returns the next element.
      * @return the next element
      * @throws NoSuchElementException if there is none.
      */
-    public Object nextElement()
+    public V nextElement()
     {
-      HashEntry entry = (HashEntry) super.nextElement();
-      Object retVal = null;
+      HashEntry<K,V> entry = (HashEntry<K,V>) enumerator.nextElement();
+      V retVal = null;
       if (entry != null)
         retVal = entry.value;
       return retVal;