Merged gcj-eclipse branch to trunk.
From-SVN: r120621
This commit is contained in:
parent
c648dedbde
commit
97b8365caf
17478 changed files with 606493 additions and 100744 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)super.next()).value;
|
||||
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()
|
||||
{
|
||||
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;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue