commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bay...@apache.org
Subject svn commit: r814997 [8/18] - in /commons/proper/collections/trunk/src: java/org/apache/commons/collections/ java/org/apache/commons/collections/bag/ java/org/apache/commons/collections/bidimap/ java/org/apache/commons/collections/buffer/ java/org/apach...
Date Tue, 15 Sep 2009 05:30:02 GMT
Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractHashedMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractHashedMap.java?rev=814997&r1=814996&r2=814997&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractHashedMap.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractHashedMap.java Tue Sep 15 05:29:56 2009
@@ -59,15 +59,15 @@
  * @author Stephen Colebourne
  * @author Christian Siefkes
  */
-public class AbstractHashedMap extends AbstractMap implements IterableMap {
-    
+public class AbstractHashedMap<K, V> extends AbstractMap<K, V> implements IterableMap<K, V> {
+
     protected static final String NO_NEXT_ENTRY = "No next() entry in the iteration";
     protected static final String NO_PREVIOUS_ENTRY = "No previous() entry in the iteration";
     protected static final String REMOVE_INVALID = "remove() can only be called once after next()";
     protected static final String GETKEY_INVALID = "getKey() can only be called after next() and before remove()";
     protected static final String GETVALUE_INVALID = "getValue() can only be called after next() and before remove()";
     protected static final String SETVALUE_INVALID = "setValue() can only be called after next() and before remove()";
-    
+
     /** The default capacity to use */
     protected static final int DEFAULT_CAPACITY = 16;
     /** The default threshold to use */
@@ -78,23 +78,23 @@
     protected static final int MAXIMUM_CAPACITY = 1 << 30;
     /** An object for masking null */
     protected static final Object NULL = new Object();
-    
+
     /** Load factor, normally 0.75 */
     protected transient float loadFactor;
     /** The size of the map */
     protected transient int size;
     /** Map entries */
-    protected transient HashEntry[] data;
+    protected transient HashEntry<K, V>[] data;
     /** Size at which to rehash */
     protected transient int threshold;
     /** Modification count for iterators */
     protected transient int modCount;
     /** Entry set */
-    protected transient EntrySet entrySet;
+    protected transient EntrySet<K, V> entrySet;
     /** Key set */
-    protected transient KeySet keySet;
+    protected transient KeySet<K> keySet;
     /** Values */
-    protected transient Values values;
+    protected transient Values<V> values;
 
     /**
      * Constructor only used in deserialization, do not use otherwise.
@@ -105,11 +105,12 @@
 
     /**
      * Constructor which performs no validation on the passed in parameters.
-     * 
+     *
      * @param initialCapacity  the initial capacity, must be a power of two
      * @param loadFactor  the load factor, must be &gt; 0.0f and generally &lt; 1.0f
      * @param threshold  the threshold, must be sensible
      */
+    @SuppressWarnings("unchecked")
     protected AbstractHashedMap(int initialCapacity, float loadFactor, int threshold) {
         super();
         this.loadFactor = loadFactor;
@@ -120,7 +121,7 @@
 
     /**
      * Constructs a new, empty map with the specified initial capacity and
-     * default load factor. 
+     * default load factor.
      *
      * @param initialCapacity  the initial capacity
      * @throws IllegalArgumentException if the initial capacity is less than one
@@ -131,13 +132,14 @@
 
     /**
      * Constructs a new, empty map with the specified initial capacity and
-     * load factor. 
+     * load factor.
      *
      * @param initialCapacity  the initial capacity
      * @param loadFactor  the load factor
      * @throws IllegalArgumentException if the initial capacity is less than one
      * @throws IllegalArgumentException if the load factor is less than or equal to zero
      */
+    @SuppressWarnings("unchecked")
     protected AbstractHashedMap(int initialCapacity, float loadFactor) {
         super();
         if (initialCapacity < 1) {
@@ -159,7 +161,7 @@
      * @param map  the map to copy
      * @throws NullPointerException if the map is null
      */
-    protected AbstractHashedMap(Map map) {
+    protected AbstractHashedMap(Map<K, V> map) {
         this(Math.max(2 * map.size(), DEFAULT_CAPACITY), DEFAULT_LOAD_FACTOR);
         _putAll(map);
     }
@@ -173,14 +175,14 @@
     //-----------------------------------------------------------------------
     /**
      * Gets the value mapped to the key specified.
-     * 
+     *
      * @param key  the key
      * @return the mapped value, null if no match
      */
-    public Object get(Object key) {
+    public V get(Object key) {
         key = convertKey(key);
         int hashCode = hash(key);
-        HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
+        HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
         while (entry != null) {
             if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
                 return entry.getValue();
@@ -192,7 +194,7 @@
 
     /**
      * Gets the size of the map.
-     * 
+     *
      * @return the size
      */
     public int size() {
@@ -201,7 +203,7 @@
 
     /**
      * Checks whether the map is currently empty.
-     * 
+     *
      * @return true if the map is currently size zero
      */
     public boolean isEmpty() {
@@ -211,14 +213,14 @@
     //-----------------------------------------------------------------------
     /**
      * Checks whether the map contains the specified key.
-     * 
+     *
      * @param key  the key to search for
      * @return true if the map contains the key
      */
     public boolean containsKey(Object key) {
         key = convertKey(key);
         int hashCode = hash(key);
-        HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
+        HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
         while (entry != null) {
             if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
                 return true;
@@ -230,14 +232,14 @@
 
     /**
      * Checks whether the map contains the specified value.
-     * 
+     *
      * @param value  the value to search for
      * @return true if the map contains the value
      */
     public boolean containsValue(Object value) {
         if (value == null) {
             for (int i = 0, isize = data.length; i < isize; i++) {
-                HashEntry entry = data[i];
+                HashEntry<K, V> entry = data[i];
                 while (entry != null) {
                     if (entry.getValue() == null) {
                         return true;
@@ -247,7 +249,7 @@
             }
         } else {
             for (int i = 0, isize = data.length; i < isize; i++) {
-                HashEntry entry = data[i];
+                HashEntry<K, V> entry = data[i];
                 while (entry != null) {
                     if (isEqualValue(value, entry.getValue())) {
                         return true;
@@ -262,25 +264,25 @@
     //-----------------------------------------------------------------------
     /**
      * Puts a key-value mapping into this map.
-     * 
+     *
      * @param key  the key to add
      * @param value  the value to add
      * @return the value previously mapped to this key, null if none
      */
-    public Object put(Object key, Object value) {
-        key = convertKey(key);
-        int hashCode = hash(key);
+    public V put(K key, V value) {
+        Object convertedKey = convertKey(key);
+        int hashCode = hash(convertedKey);
         int index = hashIndex(hashCode, data.length);
-        HashEntry entry = data[index];
+        HashEntry<K, V> entry = data[index];
         while (entry != null) {
-            if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
-                Object oldValue = entry.getValue();
+            if (entry.hashCode == hashCode && isEqualKey(convertedKey, entry.key)) {
+                V oldValue = entry.getValue();
                 updateEntry(entry, value);
                 return oldValue;
             }
             entry = entry.next;
         }
-        
+
         addMapping(index, hashCode, key, value);
         return null;
     }
@@ -290,11 +292,11 @@
      * <p>
      * This implementation iterates around the specified map and
      * uses {@link #put(Object, Object)}.
-     * 
+     *
      * @param map  the map to add
      * @throws NullPointerException if the map is null
      */
-    public void putAll(Map map) {
+    public void putAll(Map<? extends K, ? extends V> map) {
         _putAll(map);
     }
 
@@ -310,34 +312,33 @@
      * @param map  the map to add
      * @throws NullPointerException if the map is null
      */
-    private void _putAll(Map map) {
+    private void _putAll(Map<? extends K, ? extends V> map) {
         int mapSize = map.size();
         if (mapSize == 0) {
             return;
         }
         int newSize = (int) ((size + mapSize) / loadFactor + 1);
         ensureCapacity(calculateNewCapacity(newSize));
-        for (Iterator it = map.entrySet().iterator(); it.hasNext();) {
-            Map.Entry entry = (Map.Entry) it.next();
+        for (Map.Entry<? extends K, ? extends V> entry: map.entrySet()) {
             put(entry.getKey(), entry.getValue());
         }
     }
 
     /**
      * Removes the specified mapping from this map.
-     * 
+     *
      * @param key  the mapping to remove
      * @return the value mapped to the removed key, null if key not in map
      */
-    public Object remove(Object key) {
+    public V remove(Object key) {
         key = convertKey(key);
         int hashCode = hash(key);
         int index = hashIndex(hashCode, data.length);
-        HashEntry entry = data[index];
-        HashEntry previous = null;
+        HashEntry<K, V> entry = data[index];
+        HashEntry<K, V> previous = null;
         while (entry != null) {
             if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
-                Object oldValue = entry.getValue();
+                V oldValue = entry.getValue();
                 removeMapping(entry, index, previous);
                 return oldValue;
             }
@@ -353,7 +354,7 @@
      */
     public void clear() {
         modCount++;
-        HashEntry[] data = this.data;
+        HashEntry<K, V>[] data = this.data;
         for (int i = data.length - 1; i >= 0; i--) {
             data[i] = null;
         }
@@ -368,19 +369,19 @@
      * <p>
      * The reverse conversion can be changed, if required, by overriding the
      * getKey() method in the hash entry.
-     * 
+     *
      * @param key  the key convert
      * @return the converted key
      */
     protected Object convertKey(Object key) {
         return (key == null ? NULL : key);
     }
-    
+
     /**
      * Gets the hash code for the key specified.
      * This implementation uses the additional hashing routine from JDK1.4.
      * Subclasses can override this to return alternate hash codes.
-     * 
+     *
      * @param key  the key to get a hash code for
      * @return the hash code
      */
@@ -393,12 +394,12 @@
         h ^=  (h >>> 10);
         return h;
     }
-    
+
     /**
      * Compares two keys, in internal converted form, to see if they are equal.
      * This implementation uses the equals method and assumes neither key is null.
      * Subclasses can override this to match differently.
-     * 
+     *
      * @param key1  the first key to compare passed in from outside
      * @param key2  the second key extracted from the entry via <code>entry.key</code>
      * @return true if equal
@@ -406,12 +407,12 @@
     protected boolean isEqualKey(Object key1, Object key2) {
         return (key1 == key2 || key1.equals(key2));
     }
-    
+
     /**
      * Compares two values, in external form, to see if they are equal.
      * This implementation uses the equals method and assumes neither value is null.
      * Subclasses can override this to match differently.
-     * 
+     *
      * @param value1  the first value to compare passed in from outside
      * @param value2  the second value extracted from the entry via <code>getValue()</code>
      * @return true if equal
@@ -419,12 +420,12 @@
     protected boolean isEqualValue(Object value1, Object value2) {
         return (value1 == value2 || value1.equals(value2));
     }
-    
+
     /**
      * Gets the index into the data storage for the hashCode specified.
      * This implementation uses the least significant bits of the hashCode.
      * Subclasses can override this to return alternate bucketing.
-     * 
+     *
      * @param hashCode  the hash code to use
      * @param dataSize  the size of the data to pick a bucket from
      * @return the bucket index
@@ -432,7 +433,7 @@
     protected int hashIndex(int hashCode, int dataSize) {
         return hashCode & (dataSize - 1);
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * Gets the entry mapped to the key specified.
@@ -440,14 +441,14 @@
      * This method exists for subclasses that may need to perform a multi-step
      * process accessing the entry. The public methods in this class don't use this
      * method to gain a small performance boost.
-     * 
+     *
      * @param key  the key
      * @return the entry, null if no match
      */
-    protected HashEntry getEntry(Object key) {
+    protected HashEntry<K, V> getEntry(Object key) {
         key = convertKey(key);
         int hashCode = hash(key);
-        HashEntry entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
+        HashEntry<K, V> entry = data[hashIndex(hashCode, data.length)]; // no local for hash index
         while (entry != null) {
             if (entry.hashCode == hashCode && isEqualKey(key, entry.key)) {
                 return entry;
@@ -463,33 +464,33 @@
      * <p>
      * This implementation calls <code>setValue()</code> on the entry.
      * Subclasses could override to handle changes to the map.
-     * 
+     *
      * @param entry  the entry to update
      * @param newValue  the new value to store
      */
-    protected void updateEntry(HashEntry entry, Object newValue) {
+    protected void updateEntry(HashEntry<K, V> entry, V newValue) {
         entry.setValue(newValue);
     }
-    
+
     /**
      * Reuses an existing key-value mapping, storing completely new data.
      * <p>
      * This implementation sets all the data fields on the entry.
      * Subclasses could populate additional entry fields.
-     * 
+     *
      * @param entry  the entry to update, not null
      * @param hashIndex  the index in the data array
      * @param hashCode  the hash code of the key to add
      * @param key  the key to add
      * @param value  the value to add
      */
-    protected void reuseEntry(HashEntry entry, int hashIndex, int hashCode, Object key, Object value) {
+    protected void reuseEntry(HashEntry<K, V> entry, int hashIndex, int hashCode, K key, V value) {
         entry.next = data[hashIndex];
         entry.hashCode = hashCode;
         entry.key = key;
         entry.value = value;
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * Adds a new key-value mapping into this map.
@@ -498,37 +499,37 @@
      * and <code>checkCapacity()</code>.
      * It also handles changes to <code>modCount</code> and <code>size</code>.
      * Subclasses could override to fully control adds to the map.
-     * 
+     *
      * @param hashIndex  the index into the data array to store at
      * @param hashCode  the hash code of the key to add
      * @param key  the key to add
      * @param value  the value to add
      */
-    protected void addMapping(int hashIndex, int hashCode, Object key, Object value) {
+    protected void addMapping(int hashIndex, int hashCode, K key, V value) {
         modCount++;
-        HashEntry entry = createEntry(data[hashIndex], hashCode, key, value);
+        HashEntry<K, V> entry = createEntry(data[hashIndex], hashCode, key, value);
         addEntry(entry, hashIndex);
         size++;
         checkCapacity();
     }
-    
+
     /**
      * Creates an entry to store the key-value data.
      * <p>
      * This implementation creates a new HashEntry instance.
      * Subclasses can override this to return a different storage class,
      * or implement caching.
-     * 
+     *
      * @param next  the next entry in sequence
      * @param hashCode  the hash code to use
      * @param key  the key to store
      * @param value  the value to store
      * @return the newly created entry
      */
-    protected HashEntry createEntry(HashEntry next, int hashCode, Object key, Object value) {
-        return new HashEntry(next, hashCode, key, value);
+    protected HashEntry<K, V> createEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
+        return new HashEntry<K, V>(next, hashCode, convertKey(key), value);
     }
-    
+
     /**
      * Adds an entry into this map.
      * <p>
@@ -538,10 +539,10 @@
      * @param entry  the entry to add
      * @param hashIndex  the index into the data array to store at
      */
-    protected void addEntry(HashEntry entry, int hashIndex) {
+    protected void addEntry(HashEntry<K, V> entry, int hashIndex) {
         data[hashIndex] = entry;
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * Removes a mapping from the map.
@@ -549,51 +550,51 @@
      * This implementation calls <code>removeEntry()</code> and <code>destroyEntry()</code>.
      * It also handles changes to <code>modCount</code> and <code>size</code>.
      * Subclasses could override to fully control removals from the map.
-     * 
+     *
      * @param entry  the entry to remove
      * @param hashIndex  the index into the data structure
      * @param previous  the previous entry in the chain
      */
-    protected void removeMapping(HashEntry entry, int hashIndex, HashEntry previous) {
+    protected void removeMapping(HashEntry<K, V> entry, int hashIndex, HashEntry<K, V> previous) {
         modCount++;
         removeEntry(entry, hashIndex, previous);
         size--;
         destroyEntry(entry);
     }
-    
+
     /**
      * Removes an entry from the chain stored in a particular index.
      * <p>
      * This implementation removes the entry from the data storage table.
      * The size is not updated.
      * Subclasses could override to handle changes to the map.
-     * 
+     *
      * @param entry  the entry to remove
      * @param hashIndex  the index into the data structure
      * @param previous  the previous entry in the chain
      */
-    protected void removeEntry(HashEntry entry, int hashIndex, HashEntry previous) {
+    protected void removeEntry(HashEntry<K, V> entry, int hashIndex, HashEntry<K, V> previous) {
         if (previous == null) {
             data[hashIndex] = entry.next;
         } else {
             previous.next = entry.next;
         }
     }
-    
+
     /**
      * Kills an entry ready for the garbage collector.
      * <p>
      * This implementation prepares the HashEntry for garbage collection.
      * Subclasses can override this to implement caching (override clear as well).
-     * 
+     *
      * @param entry  the entry to destroy
      */
-    protected void destroyEntry(HashEntry entry) {
+    protected void destroyEntry(HashEntry<K, V> entry) {
         entry.next = null;
         entry.key = null;
         entry.value = null;
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * Checks the capacity of the map and enlarges it if necessary.
@@ -608,12 +609,13 @@
             }
         }
     }
-    
+
     /**
      * Changes the size of the data structure to the capacity proposed.
-     * 
+     *
      * @param newCapacity  the new capacity of the array (a power of two, less or equal to max)
      */
+    @SuppressWarnings("unchecked")
     protected void ensureCapacity(int newCapacity) {
         int oldCapacity = data.length;
         if (newCapacity <= oldCapacity) {
@@ -633,7 +635,7 @@
                     oldEntries[i] = null;  // gc
                     do {
                         HashEntry next = entry.next;
-                        int index = hashIndex(entry.hashCode, newCapacity);  
+                        int index = hashIndex(entry.hashCode, newCapacity);
                         entry.next = newEntries[index];
                         newEntries[index] = entry;
                         entry = next;
@@ -648,7 +650,7 @@
     /**
      * Calculates the new capacity of the map.
      * This implementation normalizes the capacity to a power of two.
-     * 
+     *
      * @param proposedCapacity  the proposed capacity
      * @return the normalized new capacity
      */
@@ -666,11 +668,11 @@
         }
         return newCapacity;
     }
-    
+
     /**
      * Calculates the new threshold of the map, where it will be resized.
      * This implementation uses the load factor.
-     * 
+     *
      * @param newCapacity  the new capacity
      * @param factor  the load factor
      * @return the new resize threshold
@@ -678,60 +680,60 @@
     protected int calculateThreshold(int newCapacity, float factor) {
         return (int) (newCapacity * factor);
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * Gets the <code>next</code> field from a <code>HashEntry</code>.
      * Used in subclasses that have no visibility of the field.
-     * 
+     *
      * @param entry  the entry to query, must not be null
      * @return the <code>next</code> field of the entry
      * @throws NullPointerException if the entry is null
      * @since Commons Collections 3.1
      */
-    protected HashEntry entryNext(HashEntry entry) {
+    protected HashEntry<K, V> entryNext(HashEntry<K, V> entry) {
         return entry.next;
     }
-    
+
     /**
      * Gets the <code>hashCode</code> field from a <code>HashEntry</code>.
      * Used in subclasses that have no visibility of the field.
-     * 
+     *
      * @param entry  the entry to query, must not be null
      * @return the <code>hashCode</code> field of the entry
      * @throws NullPointerException if the entry is null
      * @since Commons Collections 3.1
      */
-    protected int entryHashCode(HashEntry entry) {
+    protected int entryHashCode(HashEntry<K, V> entry) {
         return entry.hashCode;
     }
-    
+
     /**
      * Gets the <code>key</code> field from a <code>HashEntry</code>.
      * Used in subclasses that have no visibility of the field.
-     * 
+     *
      * @param entry  the entry to query, must not be null
      * @return the <code>key</code> field of the entry
      * @throws NullPointerException if the entry is null
      * @since Commons Collections 3.1
      */
-    protected Object entryKey(HashEntry entry) {
-        return entry.key;
+    protected K entryKey(HashEntry<K, V> entry) {
+        return entry.getKey();
     }
-    
+
     /**
      * Gets the <code>value</code> field from a <code>HashEntry</code>.
      * Used in subclasses that have no visibility of the field.
-     * 
+     *
      * @param entry  the entry to query, must not be null
      * @return the <code>value</code> field of the entry
      * @throws NullPointerException if the entry is null
      * @since Commons Collections 3.1
      */
-    protected Object entryValue(HashEntry entry) {
-        return entry.value;
+    protected V entryValue(HashEntry<K, V> entry) {
+        return entry.getValue();
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * Gets an iterator over the map.
@@ -741,90 +743,90 @@
      * methods to get the key and value, and set the value.
      * It avoids the need to create an entrySet/keySet/values object.
      * It also avoids creating the Map.Entry object.
-     * 
+     *
      * @return the map iterator
      */
-    public MapIterator mapIterator() {
+    public MapIterator<K, V> mapIterator() {
         if (size == 0) {
-            return EmptyMapIterator.INSTANCE;
+            return EmptyMapIterator.<K, V>getInstance();
         }
-        return new HashMapIterator(this);
+        return new HashMapIterator<K, V>(this);
     }
 
     /**
      * MapIterator implementation.
      */
-    protected static class HashMapIterator extends HashIterator implements MapIterator {
-        
-        protected HashMapIterator(AbstractHashedMap parent) {
+    protected static class HashMapIterator<K, V> extends HashIterator<K, V> implements MapIterator<K, V> {
+
+        protected HashMapIterator(AbstractHashedMap<K, V> parent) {
             super(parent);
         }
 
-        public Object next() {
+        public K next() {
             return super.nextEntry().getKey();
         }
 
-        public Object getKey() {
-            HashEntry current = currentEntry();
+        public K getKey() {
+            HashEntry<K, V> current = currentEntry();
             if (current == null) {
                 throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
             }
             return current.getKey();
         }
 
-        public Object getValue() {
-            HashEntry current = currentEntry();
+        public V getValue() {
+            HashEntry<K, V> current = currentEntry();
             if (current == null) {
                 throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
             }
             return current.getValue();
         }
 
-        public Object setValue(Object value) {
-            HashEntry current = currentEntry();
+        public V setValue(V value) {
+            HashEntry<K, V> current = currentEntry();
             if (current == null) {
                 throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
             }
             return current.setValue(value);
         }
     }
-    
-    //-----------------------------------------------------------------------    
+
+    //-----------------------------------------------------------------------
     /**
      * Gets the entrySet view of the map.
      * Changes made to the view affect this map.
      * To simply iterate through the entries, use {@link #mapIterator()}.
-     * 
+     *
      * @return the entrySet view
      */
-    public Set entrySet() {
+    public Set<Map.Entry<K, V>> entrySet() {
         if (entrySet == null) {
-            entrySet = new EntrySet(this);
+            entrySet = new EntrySet<K, V>(this);
         }
         return entrySet;
     }
-    
+
     /**
      * Creates an entry set iterator.
      * Subclasses can override this to return iterators with different properties.
-     * 
+     *
      * @return the entrySet iterator
      */
-    protected Iterator createEntrySetIterator() {
+    protected Iterator<Map.Entry<K, V>> createEntrySetIterator() {
         if (size() == 0) {
-            return EmptyIterator.INSTANCE;
+            return EmptyIterator.<Map.Entry<K, V>>getInstance();
         }
-        return new EntrySetIterator(this);
+        return new EntrySetIterator<K, V>(this);
     }
 
     /**
      * EntrySet implementation.
      */
-    protected static class EntrySet extends AbstractSet {
+    protected static class EntrySet<K, V> extends AbstractSet<Map.Entry<K, V>> {
         /** The parent map */
-        protected final AbstractHashedMap parent;
-        
-        protected EntrySet(AbstractHashedMap parent) {
+        protected final AbstractHashedMap<K, V> parent;
+
+        protected EntrySet(AbstractHashedMap<K, V> parent) {
             super();
             this.parent = parent;
         }
@@ -832,20 +834,20 @@
         public int size() {
             return parent.size();
         }
-        
+
         public void clear() {
             parent.clear();
         }
-        
+
         public boolean contains(Object entry) {
             if (entry instanceof Map.Entry) {
-                Map.Entry e = (Map.Entry) entry;
-                Entry match = parent.getEntry(e.getKey());
+                Map.Entry<?, ?> e = (Map.Entry<?, ?>) entry;
+                Entry<K, V> match = parent.getEntry(e.getKey());
                 return (match != null && match.equals(e));
             }
             return false;
         }
-        
+
         public boolean remove(Object obj) {
             if (obj instanceof Map.Entry == false) {
                 return false;
@@ -853,13 +855,12 @@
             if (contains(obj) == false) {
                 return false;
             }
-            Map.Entry entry = (Map.Entry) obj;
-            Object key = entry.getKey();
-            parent.remove(key);
+            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
+            parent.remove(entry.getKey());
             return true;
         }
 
-        public Iterator iterator() {
+        public Iterator<Map.Entry<K, V>> iterator() {
             return parent.createEntrySetIterator();
         }
     }
@@ -867,28 +868,28 @@
     /**
      * EntrySet iterator.
      */
-    protected static class EntrySetIterator extends HashIterator {
-        
-        protected EntrySetIterator(AbstractHashedMap parent) {
+    protected static class EntrySetIterator<K, V> extends HashIterator<K, V> implements Iterator<Map.Entry<K, V>> {
+
+        protected EntrySetIterator(AbstractHashedMap<K, V> parent) {
             super(parent);
         }
 
-        public Object next() {
+        public Map.Entry<K, V> next() {
             return super.nextEntry();
         }
     }
 
-    //-----------------------------------------------------------------------    
+    //-----------------------------------------------------------------------
     /**
      * Gets the keySet view of the map.
      * Changes made to the view affect this map.
      * To simply iterate through the keys, use {@link #mapIterator()}.
-     * 
+     *
      * @return the keySet view
      */
-    public Set keySet() {
+    public Set<K> keySet() {
         if (keySet == null) {
-            keySet = new KeySet(this);
+            keySet = new KeySet<K>(this);
         }
         return keySet;
     }
@@ -896,24 +897,24 @@
     /**
      * Creates a key set iterator.
      * Subclasses can override this to return iterators with different properties.
-     * 
+     *
      * @return the keySet iterator
      */
-    protected Iterator createKeySetIterator() {
+    protected Iterator<K> createKeySetIterator() {
         if (size() == 0) {
-            return EmptyIterator.INSTANCE;
+            return EmptyIterator.<K>getInstance();
         }
-        return new KeySetIterator(this);
+        return new KeySetIterator<K>(this);
     }
 
     /**
      * KeySet implementation.
      */
-    protected static class KeySet extends AbstractSet {
+    protected static class KeySet<K> extends AbstractSet<K> {
         /** The parent map */
-        protected final AbstractHashedMap parent;
-        
-        protected KeySet(AbstractHashedMap parent) {
+        protected final AbstractHashedMap<K, ?> parent;
+
+        protected KeySet(AbstractHashedMap<K, ?> parent) {
             super();
             this.parent = parent;
         }
@@ -921,22 +922,22 @@
         public int size() {
             return parent.size();
         }
-        
+
         public void clear() {
             parent.clear();
         }
-        
+
         public boolean contains(Object key) {
             return parent.containsKey(key);
         }
-        
+
         public boolean remove(Object key) {
             boolean result = parent.containsKey(key);
             parent.remove(key);
             return result;
         }
 
-        public Iterator iterator() {
+        public Iterator<K> iterator() {
             return parent.createKeySetIterator();
         }
     }
@@ -944,28 +945,29 @@
     /**
      * KeySet iterator.
      */
-    protected static class KeySetIterator extends EntrySetIterator {
-        
-        protected KeySetIterator(AbstractHashedMap parent) {
-            super(parent);
+    protected static class KeySetIterator<K> extends HashIterator<K, Object> implements Iterator<K> {
+
+        @SuppressWarnings("unchecked")
+        protected KeySetIterator(AbstractHashedMap<K, ?> parent) {
+            super((AbstractHashedMap<K, Object>) parent);
         }
 
-        public Object next() {
+        public K next() {
             return super.nextEntry().getKey();
         }
     }
-    
-    //-----------------------------------------------------------------------    
+
+    //-----------------------------------------------------------------------
     /**
      * Gets the values view of the map.
      * Changes made to the view affect this map.
      * To simply iterate through the values, use {@link #mapIterator()}.
-     * 
+     *
      * @return the values view
      */
-    public Collection values() {
+    public Collection<V> values() {
         if (values == null) {
-            values = new Values(this);
+            values = new Values<V>(this);
         }
         return values;
     }
@@ -973,24 +975,24 @@
     /**
      * Creates a values iterator.
      * Subclasses can override this to return iterators with different properties.
-     * 
+     *
      * @return the values iterator
      */
-    protected Iterator createValuesIterator() {
+    protected Iterator<V> createValuesIterator() {
         if (size() == 0) {
-            return EmptyIterator.INSTANCE;
+            return EmptyIterator.<V>getInstance();
         }
-        return new ValuesIterator(this);
+        return new ValuesIterator<V>(this);
     }
 
     /**
      * Values implementation.
      */
-    protected static class Values extends AbstractCollection {
+    protected static class Values<V> extends AbstractCollection<V> {
         /** The parent map */
-        protected final AbstractHashedMap parent;
-        
-        protected Values(AbstractHashedMap parent) {
+        protected final AbstractHashedMap<?, V> parent;
+
+        protected Values(AbstractHashedMap<?, V> parent) {
             super();
             this.parent = parent;
         }
@@ -998,16 +1000,16 @@
         public int size() {
             return parent.size();
         }
-        
+
         public void clear() {
             parent.clear();
         }
-        
+
         public boolean contains(Object value) {
             return parent.containsValue(value);
         }
-        
-        public Iterator iterator() {
+
+        public Iterator<V> iterator() {
             return parent.createValuesIterator();
         }
     }
@@ -1015,17 +1017,18 @@
     /**
      * Values iterator.
      */
-    protected static class ValuesIterator extends HashIterator {
-        
-        protected ValuesIterator(AbstractHashedMap parent) {
-            super(parent);
+    protected static class ValuesIterator<V> extends HashIterator<Object, V> implements Iterator<V> {
+
+        @SuppressWarnings("unchecked")
+        protected ValuesIterator(AbstractHashedMap<?, V> parent) {
+            super((AbstractHashedMap<Object, V>) parent);
         }
 
-        public Object next() {
+        public V next() {
             return super.nextEntry().getValue();
         }
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * HashEntry used to store the data.
@@ -1035,38 +1038,44 @@
      * The <code>entryXxx()</code> methods on <code>AbstractHashedMap</code> exist
      * to provide the necessary access.
      */
-    protected static class HashEntry implements Map.Entry, KeyValue {
+    protected static class HashEntry<K, V> implements Map.Entry<K, V>, KeyValue<K, V> {
         /** The next entry in the hash chain */
-        protected HashEntry next;
+        protected HashEntry<K, V> next;
         /** The hash code of the key */
         protected int hashCode;
         /** The key */
         protected Object key;
         /** The value */
         protected Object value;
-        
-        protected HashEntry(HashEntry next, int hashCode, Object key, Object value) {
+
+        protected HashEntry(HashEntry<K, V> next, int hashCode, Object key, V value) {
             super();
             this.next = next;
             this.hashCode = hashCode;
             this.key = key;
             this.value = value;
         }
-        
-        public Object getKey() {
-            return (key == NULL ? null : key);
-        }
-        
-        public Object getValue() {
-            return value;
+
+        @SuppressWarnings("unchecked")
+        public K getKey() {
+            if (key == NULL) {
+                return null;
+            }
+            return (K) key;
         }
-        
-        public Object setValue(Object value) {
+
+        @SuppressWarnings("unchecked")
+        public V getValue() {
+            return (V) value;
+        }
+
+        @SuppressWarnings("unchecked")
+        public V setValue(V value) {
             Object old = this.value;
             this.value = value;
-            return old;
+            return (V) old;
         }
-        
+
         public boolean equals(Object obj) {
             if (obj == this) {
                 return true;
@@ -1074,44 +1083,44 @@
             if (obj instanceof Map.Entry == false) {
                 return false;
             }
-            Map.Entry other = (Map.Entry) obj;
+            Map.Entry<?, ?> other = (Map.Entry<?, ?>) obj;
             return
                 (getKey() == null ? other.getKey() == null : getKey().equals(other.getKey())) &&
                 (getValue() == null ? other.getValue() == null : getValue().equals(other.getValue()));
         }
-        
+
         public int hashCode() {
             return (getKey() == null ? 0 : getKey().hashCode()) ^
-                   (getValue() == null ? 0 : getValue().hashCode()); 
+                   (getValue() == null ? 0 : getValue().hashCode());
         }
-        
+
         public String toString() {
             return new StringBuffer().append(getKey()).append('=').append(getValue()).toString();
         }
     }
-    
+
     /**
      * Base Iterator
      */
-    protected static abstract class HashIterator implements Iterator {
-        
+    protected static abstract class HashIterator<K, V> {
+
         /** The parent map */
-        protected final AbstractHashedMap parent;
+        protected final AbstractHashedMap<K, V> parent;
         /** The current index into the array of buckets */
         protected int hashIndex;
         /** The last returned entry */
-        protected HashEntry last;
+        protected HashEntry<K, V> last;
         /** The next entry */
-        protected HashEntry next;
+        protected HashEntry<K, V> next;
         /** The modification count expected */
         protected int expectedModCount;
-        
-        protected HashIterator(AbstractHashedMap parent) {
+
+        protected HashIterator(AbstractHashedMap<K, V> parent) {
             super();
             this.parent = parent;
-            HashEntry[] data = parent.data;
+            HashEntry<K, V>[] data = parent.data;
             int i = data.length;
-            HashEntry next = null;
+            HashEntry<K, V> next = null;
             while (i > 0 && next == null) {
                 next = data[--i];
             }
@@ -1124,17 +1133,17 @@
             return (next != null);
         }
 
-        protected HashEntry nextEntry() { 
+        protected HashEntry<K, V> nextEntry() {
             if (parent.modCount != expectedModCount) {
                 throw new ConcurrentModificationException();
             }
-            HashEntry newCurrent = next;
+            HashEntry<K, V> newCurrent = next;
             if (newCurrent == null)  {
                 throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY);
             }
-            HashEntry[] data = parent.data;
+            HashEntry<K, V>[] data = parent.data;
             int i = hashIndex;
-            HashEntry n = newCurrent.next;
+            HashEntry<K, V> n = newCurrent.next;
             while (n == null && i > 0) {
                 n = data[--i];
             }
@@ -1144,10 +1153,10 @@
             return newCurrent;
         }
 
-        protected HashEntry currentEntry() {
+        protected HashEntry<K, V> currentEntry() {
             return last;
         }
-        
+
         public void remove() {
             if (last == null) {
                 throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID);
@@ -1163,12 +1172,11 @@
         public String toString() {
             if (last != null) {
                 return "Iterator[" + last.getKey() + "=" + last.getValue() + "]";
-            } else {
-                return "Iterator[]";
             }
+            return "Iterator[]";
         }
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * Writes the map data to the stream. This method must be overridden if a
@@ -1186,14 +1194,14 @@
      * Subclasses may override if they have a specific field that must be present
      * on read before this implementation will work. Generally, the read determines
      * what must be serialized here, if anything.
-     * 
+     *
      * @param out  the output stream
      */
     protected void doWriteObject(ObjectOutputStream out) throws IOException {
         out.writeFloat(loadFactor);
         out.writeInt(data.length);
         out.writeInt(size);
-        for (MapIterator it = mapIterator(); it.hasNext();) {
+        for (MapIterator<K, V> it = mapIterator(); it.hasNext();) {
             out.writeObject(it.next());
             out.writeObject(it.getValue());
         }
@@ -1214,9 +1222,10 @@
      * <p>
      * Subclasses may override if the subclass has a specific field that must be present
      * before <code>put()</code> or <code>calculateThreshold()</code> will work correctly.
-     * 
+     *
      * @param in  the input stream
      */
+    @SuppressWarnings("unchecked")
     protected void doReadObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
         loadFactor = in.readFloat();
         int capacity = in.readInt();
@@ -1225,12 +1234,12 @@
         threshold = calculateThreshold(capacity, loadFactor);
         data = new HashEntry[capacity];
         for (int i = 0; i < size; i++) {
-            Object key = in.readObject();
-            Object value = in.readObject();
+            K key = (K) in.readObject();
+            V value = (V) in.readObject();
             put(key, value);
         }
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * Clones the map without cloning the keys or values.
@@ -1240,9 +1249,10 @@
      *
      * @return a shallow clone
      */
-    protected Object clone() {
+    @SuppressWarnings("unchecked")
+    protected AbstractHashedMap<K, V> clone() {
         try {
-            AbstractHashedMap cloned = (AbstractHashedMap) super.clone();
+            AbstractHashedMap<K, V> cloned = (AbstractHashedMap<K, V>) super.clone();
             cloned.data = new HashEntry[data.length];
             cloned.entrySet = null;
             cloned.keySet = null;
@@ -1252,18 +1262,18 @@
             cloned.init();
             cloned.putAll(this);
             return cloned;
-            
         } catch (CloneNotSupportedException ex) {
             return null;  // should never happen
         }
     }
-    
+
     /**
      * Compares this map with another.
-     * 
+     *
      * @param obj  the object to compare to
      * @return true if equal
      */
+    @SuppressWarnings("unchecked")
     public boolean equals(Object obj) {
         if (obj == this) {
             return true;
@@ -1300,12 +1310,12 @@
 
     /**
      * Gets the standard Map hashCode.
-     * 
+     *
      * @return the hash code defined in the Map interface
      */
     public int hashCode() {
         int total = 0;
-        Iterator it = createEntrySetIterator();
+        Iterator<Map.Entry<K, V>> it = createEntrySetIterator();
         while (it.hasNext()) {
             total += it.next().hashCode();
         }
@@ -1314,7 +1324,7 @@
 
     /**
      * Gets the map as a String.
-     * 
+     *
      * @return a string version of the map
      */
     public String toString() {
@@ -1324,11 +1334,11 @@
         StringBuffer buf = new StringBuffer(32 * size());
         buf.append('{');
 
-        MapIterator it = mapIterator();
+        MapIterator<K, V> it = mapIterator();
         boolean hasNext = it.hasNext();
         while (hasNext) {
-            Object key = it.next();
-            Object value = it.getValue();
+            K key = it.next();
+            V value = it.getValue();
             buf.append(key == this ? "(this Map)" : key)
                .append('=')
                .append(value == this ? "(this Map)" : value);

Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractInputCheckedMapDecorator.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractInputCheckedMapDecorator.java?rev=814997&r1=814996&r2=814997&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractInputCheckedMapDecorator.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractInputCheckedMapDecorator.java Tue Sep 15 05:29:56 2009
@@ -44,8 +44,8 @@
  *
  * @author Stephen Colebourne
  */
-abstract class AbstractInputCheckedMapDecorator
-        extends AbstractMapDecorator {
+abstract class AbstractInputCheckedMapDecorator<K, V>
+        extends AbstractMapDecorator<K, V> {
 
     /**
      * Constructor only used in deserialization, do not use otherwise.
@@ -60,7 +60,7 @@
      * @param map  the map to decorate, must not be null
      * @throws IllegalArgumentException if map is null
      */
-    protected AbstractInputCheckedMapDecorator(Map map) {
+    protected AbstractInputCheckedMapDecorator(Map<K, V> map) {
         super(map);
     }
 
@@ -79,7 +79,7 @@
      * @throws ClassCastException if the class of the specified value is invalid
      * @throws NullPointerException if the specified value is null and nulls are invalid
      */
-    protected abstract Object checkSetValue(Object value);
+    protected abstract V checkSetValue(V value);
 
     /**
      * Hook method called to determine if <code>checkSetValue</code> has any effect.
@@ -96,41 +96,43 @@
     }
 
     //-----------------------------------------------------------------------
-    public Set entrySet() {
+    public Set<Map.Entry<K, V>> entrySet() {
         if (isSetValueChecking()) {
             return new EntrySet(map.entrySet(), this);
-        } else {
-            return map.entrySet();
         }
+        return map.entrySet();
     }
 
     //-----------------------------------------------------------------------
     /**
      * Implementation of an entry set that checks additions via setValue.
      */
-    static class EntrySet extends AbstractSetDecorator {
+    @SuppressWarnings("serial")
+    private class EntrySet extends AbstractSetDecorator<Map.Entry<K, V>> {
         
         /** The parent map */
-        private final AbstractInputCheckedMapDecorator parent;
+        private final AbstractInputCheckedMapDecorator<K, V> parent;
 
-        protected EntrySet(Set set, AbstractInputCheckedMapDecorator parent) {
+        protected EntrySet(Set<Map.Entry<K, V>> set, AbstractInputCheckedMapDecorator<K, V> parent) {
             super(set);
             this.parent = parent;
         }
 
-        public Iterator iterator() {
+        public Iterator<Map.Entry<K, V>> iterator() {
             return new EntrySetIterator(collection.iterator(), parent);
         }
         
+        @SuppressWarnings("unchecked")
         public Object[] toArray() {
             Object[] array = collection.toArray();
             for (int i = 0; i < array.length; i++) {
-                array[i] = new MapEntry((Map.Entry) array[i], parent);
+                array[i] = new MapEntry((Map.Entry<K, V>) array[i], parent);
             }
             return array;
         }
         
-        public Object[] toArray(Object array[]) {
+        @SuppressWarnings("unchecked")
+        public <T> T[] toArray(T[] array) {
             Object[] result = array;
             if (array.length > 0) {
                 // we must create a new array to handle multi-threaded situations
@@ -139,12 +141,12 @@
             }
             result = collection.toArray(result);
             for (int i = 0; i < result.length; i++) {
-                result[i] = new MapEntry((Map.Entry) result[i], parent);
+                result[i] = new MapEntry((Map.Entry<K, V>) result[i], parent);
             }
 
             // check to see if result should be returned straight
             if (result.length > array.length) {
-                return result;
+                return (T[]) result;
             }
 
             // copy back into input array to fulfil the method contract
@@ -159,18 +161,18 @@
     /**
      * Implementation of an entry set iterator that checks additions via setValue.
      */
-    static class EntrySetIterator extends AbstractIteratorDecorator {
-        
+    private class EntrySetIterator extends AbstractIteratorDecorator<Map.Entry<K, V>> {
+
         /** The parent map */
-        private final AbstractInputCheckedMapDecorator parent;
-        
-        protected EntrySetIterator(Iterator iterator, AbstractInputCheckedMapDecorator parent) {
+        private final AbstractInputCheckedMapDecorator<K, V> parent;
+
+        protected EntrySetIterator(Iterator<Map.Entry<K, V>> iterator, AbstractInputCheckedMapDecorator<K, V> parent) {
             super(iterator);
             this.parent = parent;
         }
-        
-        public Object next() {
-            Map.Entry entry = (Map.Entry) iterator.next();
+
+        public Map.Entry<K, V> next() {
+            Map.Entry<K, V> entry = iterator.next();
             return new MapEntry(entry, parent);
         }
     }
@@ -178,17 +180,17 @@
     /**
      * Implementation of a map entry that checks additions via setValue.
      */
-    static class MapEntry extends AbstractMapEntryDecorator {
+    private class MapEntry extends AbstractMapEntryDecorator<K, V> {
 
         /** The parent map */
-        private final AbstractInputCheckedMapDecorator parent;
+        private final AbstractInputCheckedMapDecorator<K, V> parent;
 
-        protected MapEntry(Map.Entry entry, AbstractInputCheckedMapDecorator parent) {
+        protected MapEntry(Map.Entry<K, V> entry, AbstractInputCheckedMapDecorator<K, V> parent) {
             super(entry);
             this.parent = parent;
         }
 
-        public Object setValue(Object value) {
+        public V setValue(V value) {
             value = parent.checkSetValue(value);
             return entry.setValue(value);
         }

Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractLinkedMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractLinkedMap.java?rev=814997&r1=814996&r2=814997&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractLinkedMap.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractLinkedMap.java Tue Sep 15 05:29:56 2009
@@ -21,7 +21,6 @@
 import java.util.Map;
 import java.util.NoSuchElementException;
 
-import org.apache.commons.collections.MapIterator;
 import org.apache.commons.collections.OrderedIterator;
 import org.apache.commons.collections.OrderedMap;
 import org.apache.commons.collections.OrderedMapIterator;
@@ -63,10 +62,10 @@
  * @author java util LinkedHashMap
  * @author Stephen Colebourne
  */
-public class AbstractLinkedMap extends AbstractHashedMap implements OrderedMap {
+public abstract class AbstractLinkedMap<K, V> extends AbstractHashedMap<K, V> implements OrderedMap<K, V> {
     
     /** Header in the linked list */
-    protected transient LinkEntry header;
+    protected transient LinkEntry<K, V> header;
 
     /**
      * Constructor only used in deserialization, do not use otherwise.
@@ -115,7 +114,7 @@
      * @param map  the map to copy
      * @throws NullPointerException if the map is null
      */
-    protected AbstractLinkedMap(Map map) {
+    protected AbstractLinkedMap(Map<K, V> map) {
         super(map);
     }
 
@@ -127,7 +126,7 @@
      * the map entry object.
      */
     protected void init() {
-        header = (LinkEntry) createEntry(null, -1, null, null);
+        header = createEntry(null, -1, null, null);
         header.before = header.after = header;
     }
 
@@ -141,13 +140,13 @@
     public boolean containsValue(Object value) {
         // override uses faster iterator
         if (value == null) {
-            for (LinkEntry entry = header.after; entry != header; entry = entry.after) {
+            for (LinkEntry<K, V> entry = header.after; entry != header; entry = entry.after) {
                 if (entry.getValue() == null) {
                     return true;
                 }
             }
         } else {
-            for (LinkEntry entry = header.after; entry != header; entry = entry.after) {
+            for (LinkEntry<K, V> entry = header.after; entry != header; entry = entry.after) {
                 if (isEqualValue(value, entry.getValue())) {
                     return true;
                 }
@@ -172,7 +171,7 @@
      * 
      * @return the eldest key
      */
-    public Object firstKey() {
+    public K firstKey() {
         if (size == 0) {
             throw new NoSuchElementException("Map is empty");
         }
@@ -184,7 +183,7 @@
      * 
      * @return the most recently inserted key
      */
-    public Object lastKey() {
+    public K lastKey() {
         if (size == 0) {
             throw new NoSuchElementException("Map is empty");
         }
@@ -197,19 +196,23 @@
      * @param key  the key to get after
      * @return the next key
      */
-    public Object nextKey(Object key) {
-        LinkEntry entry = (LinkEntry) getEntry(key);
+    public K nextKey(Object key) {
+        LinkEntry<K, V> entry = getEntry(key);
         return (entry == null || entry.after == header ? null : entry.after.getKey());
     }
 
+    protected LinkEntry<K, V> getEntry(Object key) {
+        return (LinkEntry<K, V>) super.getEntry(key);
+    }
+
     /**
      * Gets the previous key in sequence.
      * 
      * @param key  the key to get before
      * @return the previous key
      */
-    public Object previousKey(Object key) {
-        LinkEntry entry = (LinkEntry) getEntry(key);
+    public K previousKey(Object key) {
+        LinkEntry<K, V> entry = getEntry(key);
         return (entry == null || entry.before == header ? null : entry.before.getKey());
     }
 
@@ -221,14 +224,14 @@
      * @return the key at the specified index
      * @throws IndexOutOfBoundsException if the index is invalid
      */
-    protected LinkEntry getEntry(int index) {
+    protected LinkEntry<K, V> getEntry(int index) {
         if (index < 0) {
             throw new IndexOutOfBoundsException("Index " + index + " is less than zero");
         }
         if (index >= size) {
             throw new IndexOutOfBoundsException("Index " + index + " is invalid for size " + size);
         }
-        LinkEntry entry;
+        LinkEntry<K, V> entry;
         if (index < (size / 2)) {
             // Search forwards
             entry = header.after;
@@ -251,18 +254,18 @@
      * This implementation adds the entry to the data storage table and
      * to the end of the linked list.
      * 
-     * @param entry  the entry to add
+     * @param link  the entry to add
      * @param hashIndex  the index into the data array to store at
      */
-    protected void addEntry(HashEntry entry, int hashIndex) {
-        LinkEntry link = (LinkEntry) entry;
+    protected void addEntry(HashEntry<K, V> entry, int hashIndex) {
+        LinkEntry<K, V> link = (LinkEntry<K, V>) entry;
         link.after  = header;
         link.before = header.before;
         header.before.after = link;
         header.before = link;
-        data[hashIndex] = entry;
+        data[hashIndex] = link;
     }
-    
+
     /**
      * Creates an entry to store the data.
      * <p>
@@ -274,10 +277,10 @@
      * @param value  the value to store
      * @return the newly created entry
      */
-    protected HashEntry createEntry(HashEntry next, int hashCode, Object key, Object value) {
-        return new LinkEntry(next, hashCode, key, value);
+    protected LinkEntry<K, V> createEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
+        return new LinkEntry<K, V>(next, hashCode, convertKey(key), value);
     }
-    
+
     /**
      * Removes an entry from the map and the linked list.
      * <p>
@@ -288,15 +291,15 @@
      * @param hashIndex  the index into the data structure
      * @param previous  the previous entry in the chain
      */
-    protected void removeEntry(HashEntry entry, int hashIndex, HashEntry previous) {
-        LinkEntry link = (LinkEntry) entry;
+    protected void removeEntry(HashEntry<K, V> entry, int hashIndex, HashEntry<K, V> previous) {
+        LinkEntry<K, V> link = (LinkEntry<K, V>) entry;
         link.before.after = link.after;
         link.after.before = link.before;
         link.after = null;
         link.before = null;
         super.removeEntry(entry, hashIndex, previous);
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * Gets the <code>before</code> field from a <code>LinkEntry</code>.
@@ -307,10 +310,10 @@
      * @throws NullPointerException if the entry is null
      * @since Commons Collections 3.1
      */
-    protected LinkEntry entryBefore(LinkEntry entry) {
+    protected LinkEntry<K, V> entryBefore(LinkEntry<K, V> entry) {
         return entry.before;
     }
-    
+
     /**
      * Gets the <code>after</code> field from a <code>LinkEntry</code>.
      * Used in subclasses that have no visibility of the field.
@@ -320,87 +323,64 @@
      * @throws NullPointerException if the entry is null
      * @since Commons Collections 3.1
      */
-    protected LinkEntry entryAfter(LinkEntry entry) {
+    protected LinkEntry<K, V> entryAfter(LinkEntry<K, V> entry) {
         return entry.after;
     }
-    
-    //-----------------------------------------------------------------------
-    /**
-     * Gets an iterator over the map.
-     * Changes made to the iterator affect this map.
-     * <p>
-     * A MapIterator returns the keys in the map. It also provides convenient
-     * methods to get the key and value, and set the value.
-     * It avoids the need to create an entrySet/keySet/values object.
-     * 
-     * @return the map iterator
-     */
-    public MapIterator mapIterator() {
-        if (size == 0) {
-            return EmptyOrderedMapIterator.INSTANCE;
-        }
-        return new LinkMapIterator(this);
-    }
 
+    //-----------------------------------------------------------------------
     /**
-     * Gets a bidirectional iterator over the map.
-     * Changes made to the iterator affect this map.
-     * <p>
-     * A MapIterator returns the keys in the map. It also provides convenient
-     * methods to get the key and value, and set the value.
-     * It avoids the need to create an entrySet/keySet/values object.
-     * 
-     * @return the map iterator
+     * {@inheritDoc}
      */
-    public OrderedMapIterator orderedMapIterator() {
+    public OrderedMapIterator<K, V> mapIterator() {
         if (size == 0) {
-            return EmptyOrderedMapIterator.INSTANCE;
+            return EmptyOrderedMapIterator.<K, V>getInstance();
         }
-        return new LinkMapIterator(this);
+        return new LinkMapIterator<K, V>(this);
     }
 
     /**
      * MapIterator implementation.
      */
-    protected static class LinkMapIterator extends LinkIterator implements OrderedMapIterator {
-        
-        protected LinkMapIterator(AbstractLinkedMap parent) {
+    protected static class LinkMapIterator<K, V> extends LinkIterator<K, V> implements
+            OrderedMapIterator<K, V>, ResettableIterator<K> {
+
+        protected LinkMapIterator(AbstractLinkedMap<K, V> parent) {
             super(parent);
         }
 
-        public Object next() {
+        public K next() {
             return super.nextEntry().getKey();
         }
 
-        public Object previous() {
+        public K previous() {
             return super.previousEntry().getKey();
         }
 
-        public Object getKey() {
-            HashEntry current = currentEntry();
+        public K getKey() {
+            LinkEntry<K, V> current = currentEntry();
             if (current == null) {
                 throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
             }
             return current.getKey();
         }
 
-        public Object getValue() {
-            HashEntry current = currentEntry();
+        public V getValue() {
+            LinkEntry<K, V> current = currentEntry();
             if (current == null) {
                 throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
             }
             return current.getValue();
         }
 
-        public Object setValue(Object value) {
-            HashEntry current = currentEntry();
+        public V setValue(V value) {
+            LinkEntry<K, V> current = currentEntry();
             if (current == null) {
                 throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
             }
             return current.setValue(value);
         }
     }
-    
+
     //-----------------------------------------------------------------------    
     /**
      * Creates an entry set iterator.
@@ -408,27 +388,28 @@
      * 
      * @return the entrySet iterator
      */
-    protected Iterator createEntrySetIterator() {
+    protected Iterator<Map.Entry<K, V>> createEntrySetIterator() {
         if (size() == 0) {
-            return EmptyOrderedIterator.INSTANCE;
+            return EmptyOrderedIterator.<Map.Entry<K, V>>getInstance();
         }
-        return new EntrySetIterator(this);
+        return new EntrySetIterator<K, V>(this);
     }
 
     /**
      * EntrySet iterator.
      */
-    protected static class EntrySetIterator extends LinkIterator {
-        
-        protected EntrySetIterator(AbstractLinkedMap parent) {
+    protected static class EntrySetIterator<K, V> extends LinkIterator<K, V> implements
+            OrderedIterator<Map.Entry<K, V>>, ResettableIterator<Map.Entry<K, V>> {
+
+        protected EntrySetIterator(AbstractLinkedMap<K, V> parent) {
             super(parent);
         }
 
-        public Object next() {
+        public Map.Entry<K, V> next() {
             return super.nextEntry();
         }
 
-        public Object previous() {
+        public Map.Entry<K, V> previous() {
             return super.previousEntry();
         }
     }
@@ -440,31 +421,33 @@
      * 
      * @return the keySet iterator
      */
-    protected Iterator createKeySetIterator() {
+    protected Iterator<K> createKeySetIterator() {
         if (size() == 0) {
-            return EmptyOrderedIterator.INSTANCE;
+            return EmptyOrderedIterator.<K>getInstance();
         }
-        return new KeySetIterator(this);
+        return new KeySetIterator<K>(this);
     }
 
     /**
      * KeySet iterator.
      */
-    protected static class KeySetIterator extends EntrySetIterator {
+    protected static class KeySetIterator<K> extends LinkIterator<K, Object> implements
+            OrderedIterator<K>, ResettableIterator<K> {
         
-        protected KeySetIterator(AbstractLinkedMap parent) {
-            super(parent);
+        @SuppressWarnings("unchecked")
+        protected KeySetIterator(AbstractLinkedMap<K, ?> parent) {
+            super((AbstractLinkedMap<K, Object>) parent);
         }
 
-        public Object next() {
+        public K next() {
             return super.nextEntry().getKey();
         }
 
-        public Object previous() {
+        public K previous() {
             return super.previousEntry().getKey();
         }
     }
-    
+
     //-----------------------------------------------------------------------    
     /**
      * Creates a values iterator.
@@ -472,31 +455,33 @@
      * 
      * @return the values iterator
      */
-    protected Iterator createValuesIterator() {
+    protected Iterator<V> createValuesIterator() {
         if (size() == 0) {
-            return EmptyOrderedIterator.INSTANCE;
+            return EmptyOrderedIterator.<V>getInstance();
         }
-        return new ValuesIterator(this);
+        return new ValuesIterator<V>(this);
     }
 
     /**
      * Values iterator.
      */
-    protected static class ValuesIterator extends LinkIterator {
-        
-        protected ValuesIterator(AbstractLinkedMap parent) {
-            super(parent);
+    protected static class ValuesIterator<V> extends LinkIterator<Object, V> implements
+            OrderedIterator<V>, ResettableIterator<V> {
+
+        @SuppressWarnings("unchecked")
+        protected ValuesIterator(AbstractLinkedMap<?, V> parent) {
+            super((AbstractLinkedMap<Object, V>) parent);
         }
 
-        public Object next() {
+        public V next() {
             return super.nextEntry().getValue();
         }
 
-        public Object previous() {
+        public V previous() {
             return super.previousEntry().getValue();
         }
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * LinkEntry that stores the data.
@@ -506,12 +491,12 @@
      * The <code>entryXxx()</code> methods on <code>AbstractLinkedMap</code> exist
      * to provide the necessary access.
      */
-    protected static class LinkEntry extends HashEntry {
+    protected static class LinkEntry<K, V> extends HashEntry<K, V> {
         /** The entry before this one in the order */
-        protected LinkEntry before;
+        protected LinkEntry<K, V> before;
         /** The entry after this one in the order */
-        protected LinkEntry after;
-        
+        protected LinkEntry<K, V> after;
+
         /**
          * Constructs a new entry.
          * 
@@ -520,27 +505,26 @@
          * @param key  the key
          * @param value  the value
          */
-        protected LinkEntry(HashEntry next, int hashCode, Object key, Object value) {
+        protected LinkEntry(HashEntry<K, V> next, int hashCode, Object key, V value) {
             super(next, hashCode, key, value);
         }
     }
-    
+
     /**
      * Base Iterator that iterates in link order.
      */
-    protected static abstract class LinkIterator
-            implements OrderedIterator, ResettableIterator {
-                
+    protected static abstract class LinkIterator<K, V> {
+
         /** The parent map */
-        protected final AbstractLinkedMap parent;
+        protected final AbstractLinkedMap<K, V> parent;
         /** The current (last returned) entry */
-        protected LinkEntry last;
+        protected LinkEntry<K, V> last;
         /** The next entry */
-        protected LinkEntry next;
+        protected LinkEntry<K, V> next;
         /** The modification count expected */
         protected int expectedModCount;
-        
-        protected LinkIterator(AbstractLinkedMap parent) {
+
+        protected LinkIterator(AbstractLinkedMap<K, V> parent) {
             super();
             this.parent = parent;
             this.next = parent.header.after;
@@ -550,12 +534,12 @@
         public boolean hasNext() {
             return (next != parent.header);
         }
-        
+
         public boolean hasPrevious() {
             return (next.before != parent.header);
         }
 
-        protected LinkEntry nextEntry() {
+        protected LinkEntry<K, V> nextEntry() {
             if (parent.modCount != expectedModCount) {
                 throw new ConcurrentModificationException();
             }
@@ -567,11 +551,11 @@
             return last;
         }
 
-        protected LinkEntry previousEntry() {
+        protected LinkEntry<K, V> previousEntry() {
             if (parent.modCount != expectedModCount) {
                 throw new ConcurrentModificationException();
             }
-            LinkEntry previous = next.before;
+            LinkEntry<K, V> previous = next.before;
             if (previous == parent.header)  {
                 throw new NoSuchElementException(AbstractHashedMap.NO_PREVIOUS_ENTRY);
             }
@@ -579,11 +563,11 @@
             last = previous;
             return last;
         }
-        
-        protected LinkEntry currentEntry() {
+
+        protected LinkEntry<K, V> currentEntry() {
             return last;
         }
-        
+
         public void remove() {
             if (last == null) {
                 throw new IllegalStateException(AbstractHashedMap.REMOVE_INVALID);
@@ -595,7 +579,7 @@
             last = null;
             expectedModCount = parent.modCount;
         }
-        
+
         public void reset() {
             last = null;
             next = parent.header.after;
@@ -604,10 +588,9 @@
         public String toString() {
             if (last != null) {
                 return "Iterator[" + last.getKey() + "=" + last.getValue() + "]";
-            } else {
-                return "Iterator[]";
             }
+            return "Iterator[]";
         }
     }
-    
+
 }



Mime
View raw message