commons-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bay...@apache.org
Subject svn commit: r814997 [9/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/AbstractReferenceMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractReferenceMap.java?rev=814997&r1=814996&r2=814997&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractReferenceMap.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/AbstractReferenceMap.java Tue Sep 15 05:29:56 2009
@@ -72,7 +72,7 @@
  * <code>ResettableIterator</code> and calling <code>reset()</code>.
  * <p>
  * This implementation is not synchronized.
- * You can use {@link java.util.Collections#synchronizedMap} to 
+ * You can use {@link java.util.Collections#synchronizedMap} to
  * provide synchronized access to a <code>ReferenceMap</code>.
  *
  * @see java.lang.ref.Reference
@@ -82,28 +82,51 @@
  * @author Paul Jack
  * @author Stephen Colebourne
  */
-public abstract class AbstractReferenceMap extends AbstractHashedMap {
+public abstract class AbstractReferenceMap<K, V> extends AbstractHashedMap<K, V> {
 
-    /** Constant indicating that hard references should be used */
-    public static final int HARD = 0;
+    /**
+     * Reference type enum.
+     */
+    public static enum ReferenceStrength {
+        HARD(0), SOFT(1), WEAK(2);
+
+        /** value */
+        public final int value;
+
+        /**
+         * Resolve enum from int.
+         * @param value
+         * @return ReferenceType
+         * @throws IllegalArgumentException if the specified value is invalid.
+         */
+        public static ReferenceStrength resolve(int value) {
+            switch (value) {
+            case 0:
+                return HARD;
+            case 1:
+                return SOFT;
+            case 2:
+                return WEAK;
+            default:
+                throw new IllegalArgumentException();
+            }
+        }
 
-    /** Constant indicating that soft references should be used */
-    public static final int SOFT = 1;
+        private ReferenceStrength(int value) {
+            this.value = value;
+        }
 
-    /** Constant indicating that weak references should be used */
-    public static final int WEAK = 2;
+    }
 
     /**
-     * The reference type for keys.  Must be HARD, SOFT, WEAK.
-     * @serial
+     * The reference type for keys.
      */
-    protected int keyType;
+    protected ReferenceStrength keyType;
 
     /**
-     * The reference type for values.  Must be HARD, SOFT, WEAK.
-     * @serial
+     * The reference type for values.
      */
-    protected int valueType;
+    protected ReferenceStrength valueType;
 
     /**
      * Should the value be automatically purged when the associated key has been collected?
@@ -114,7 +137,7 @@
      * ReferenceQueue used to eliminate stale mappings.
      * See purge.
      */
-    private transient ReferenceQueue queue;
+    private transient ReferenceQueue<Object> queue;
 
     //-----------------------------------------------------------------------
     /**
@@ -134,15 +157,13 @@
      *   must be {@link #HARD}, {@link #SOFT}, {@link #WEAK}
      * @param capacity  the initial capacity for the map
      * @param loadFactor  the load factor for the map
-     * @param purgeValues  should the value be automatically purged when the 
-     *   key is garbage collected 
+     * @param purgeValues  should the value be automatically purged when the
+     *   key is garbage collected
      */
     protected AbstractReferenceMap(
-            int keyType, int valueType, int capacity, 
+            ReferenceStrength keyType, ReferenceStrength valueType, int capacity,
             float loadFactor, boolean purgeValues) {
         super(capacity, loadFactor);
-        verify("keyType", keyType);
-        verify("valueType", valueType);
         this.keyType = keyType;
         this.valueType = valueType;
         this.purgeValues = purgeValues;
@@ -152,27 +173,13 @@
      * Initialise this subclass during construction, cloning or deserialization.
      */
     protected void init() {
-        queue = new ReferenceQueue();
-    }
-
-    //-----------------------------------------------------------------------
-    /**
-     * Checks the type int is a valid value.
-     * 
-     * @param name  the name for error messages
-     * @param type  the type value to check
-     * @throws IllegalArgumentException if the value if invalid
-     */
-    private static void verify(String name, int type) {
-        if ((type < HARD) || (type > WEAK)) {
-            throw new IllegalArgumentException(name + " must be HARD, SOFT, WEAK.");
-        }
+        queue = new ReferenceQueue<Object>();
     }
 
     //-----------------------------------------------------------------------
     /**
      * Gets the size of the map.
-     * 
+     *
      * @return the size
      */
     public int size() {
@@ -182,7 +189,7 @@
 
     /**
      * Checks whether the map is currently empty.
-     * 
+     *
      * @return true if the map is currently size zero
      */
     public boolean isEmpty() {
@@ -192,13 +199,13 @@
 
     /**
      * 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) {
         purgeBeforeRead();
-        Entry entry = getEntry(key);
+        Entry<K, V> entry = getEntry(key);
         if (entry == null) {
             return false;
         }
@@ -207,7 +214,7 @@
 
     /**
      * Checks whether the map contains the specified value.
-     * 
+     *
      * @param value  the value to search for
      * @return true if the map contains the value
      */
@@ -221,13 +228,13 @@
 
     /**
      * 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) {
         purgeBeforeRead();
-        Entry entry = getEntry(key);
+        Entry<K, V> entry = getEntry(key);
         if (entry == null) {
             return null;
         }
@@ -238,13 +245,13 @@
     /**
      * Puts a key-value mapping into this map.
      * Neither the key nor the value may be null.
-     * 
+     *
      * @param key  the key to add, must not be null
      * @param value  the value to add, must not be null
      * @return the value previously mapped to this key, null if none
      * @throws NullPointerException if either the key or value is null
      */
-    public Object put(Object key, Object value) {
+    public V put(K key, V value) {
         if (key == null) {
             throw new NullPointerException("null keys not allowed");
         }
@@ -255,14 +262,14 @@
         purgeBeforeWrite();
         return super.put(key, value);
     }
-    
+
     /**
      * 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) {
         if (key == null) {
             return null;
         }
@@ -282,11 +289,11 @@
     /**
      * Gets a MapIterator over the reference map.
      * The iterator only returns valid key/value pairs.
-     * 
+     *
      * @return a map iterator
      */
-    public MapIterator mapIterator() {
-        return new ReferenceMapIterator(this);
+    public MapIterator<K, V> mapIterator() {
+        return new ReferenceMapIterator<K, V>(this);
     }
 
     /**
@@ -296,9 +303,9 @@
      *
      * @return a set view of this map's entries
      */
-    public Set entrySet() {
+    public Set<Map.Entry<K, V>> entrySet() {
         if (entrySet == null) {
-            entrySet = new ReferenceEntrySet(this);
+            entrySet = new ReferenceEntrySet<K, V>(this);
         }
         return entrySet;
     }
@@ -308,9 +315,9 @@
      *
      * @return a set view of this map's keys
      */
-    public Set keySet() {
+    public Set<K> keySet() {
         if (keySet == null) {
-            keySet = new ReferenceKeySet(this);
+            keySet = new ReferenceKeySet<K>(this);
         }
         return keySet;
     }
@@ -320,9 +327,9 @@
      *
      * @return a set view of this map's values
      */
-    public Collection values() {
+    public Collection<V> values() {
         if (values == null) {
-            values = new ReferenceValues(this);
+            values = new ReferenceValues<V>(this);
         }
         return values;
     }
@@ -355,7 +362,7 @@
      * background thread.
      */
     protected void purge() {
-        Reference ref = queue.poll();
+        Reference<?> ref = queue.poll();
         while (ref != null) {
             purge(ref);
             ref = queue.poll();
@@ -364,19 +371,19 @@
 
     /**
      * Purges the specified reference.
-     * 
+     *
      * @param ref  the reference to purge
      */
-    protected void purge(Reference ref) {
+    protected void purge(Reference<?> ref) {
         // The hashCode of the reference is the hashCode of the
-        // mapping key, even if the reference refers to the 
+        // mapping key, even if the reference refers to the
         // mapping value...
         int hash = ref.hashCode();
         int index = hashIndex(hash, data.length);
-        HashEntry previous = null;
-        HashEntry entry = data[index];
+        HashEntry<K, V> previous = null;
+        HashEntry<K, V> entry = data[index];
         while (entry != null) {
-            if (((ReferenceEntry) entry).purge(ref)) {
+            if (((ReferenceEntry<K, V>) entry).purge(ref)) {
                 if (previous == null) {
                     data[index] = entry.next;
                 } else {
@@ -394,93 +401,93 @@
     //-----------------------------------------------------------------------
     /**
      * Gets the entry mapped to the key specified.
-     * 
+     *
      * @param key  the key
      * @return the entry, null if no match
      */
-    protected HashEntry getEntry(Object key) {
+    protected HashEntry<K, V> getEntry(Object key) {
         if (key == null) {
             return null;
-        } else {
-            return super.getEntry(key);
         }
+        return super.getEntry(key);
     }
 
     /**
      * Gets the hash code for a MapEntry.
      * Subclasses can override this, for example to use the identityHashCode.
-     * 
+     *
      * @param key  the key to get a hash code for, may be null
      * @param value  the value to get a hash code for, may be null
      * @return the hash code, as per the MapEntry specification
      */
     protected int hashEntry(Object key, Object value) {
         return (key == null ? 0 : key.hashCode()) ^
-               (value == null ? 0 : value.hashCode()); 
+               (value == null ? 0 : value.hashCode());
     }
-    
+
     /**
      * Compares two keys, in internal converted form, to see if they are equal.
      * <p>
      * This implementation converts the key from the entry to a real reference
      * before comparison.
-     * 
+     *
      * @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
      */
+    @SuppressWarnings("unchecked")
     protected boolean isEqualKey(Object key1, Object key2) {
-        key2 = (keyType > HARD ? ((Reference) key2).get() : key2);
+        key2 = (keyType == ReferenceStrength.HARD ? key2 : ((Reference<K>) key2).get());
         return (key1 == key2 || key1.equals(key2));
     }
-    
+
     /**
      * Creates a ReferenceEntry instead of a HashEntry.
-     * 
+     *
      * @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 ReferenceEntry(this, next, hashCode, key, value);
+    protected ReferenceEntry<K, V> createEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
+        return new ReferenceEntry<K, V>(this, next, hashCode, key, value);
     }
 
     /**
      * Creates an entry set iterator.
-     * 
+     *
      * @return the entrySet iterator
      */
-    protected Iterator createEntrySetIterator() {
-        return new ReferenceEntrySetIterator(this);
+    protected Iterator<Map.Entry<K, V>> createEntrySetIterator() {
+        return new ReferenceEntrySetIterator<K, V>(this);
     }
 
     /**
      * Creates an key set iterator.
-     * 
+     *
      * @return the keySet iterator
      */
-    protected Iterator createKeySetIterator() {
-        return new ReferenceKeySetIterator(this);
+    protected Iterator<K> createKeySetIterator() {
+        return new ReferenceKeySetIterator<K>(this);
     }
 
     /**
      * Creates an values iterator.
-     * 
+     *
      * @return the values iterator
      */
-    protected Iterator createValuesIterator() {
-        return new ReferenceValuesIterator(this);
+    protected Iterator<V> createValuesIterator() {
+        return new ReferenceValuesIterator<V>(this);
     }
 
     //-----------------------------------------------------------------------
     /**
      * EntrySet implementation.
      */
-    static class ReferenceEntrySet extends EntrySet {
-        
-        protected ReferenceEntrySet(AbstractHashedMap parent) {
+    static class ReferenceEntrySet<K, V> extends EntrySet<K, V> {
+
+        protected ReferenceEntrySet(AbstractHashedMap<K, V> parent) {
             super(parent);
         }
 
@@ -488,13 +495,11 @@
             return toArray(new Object[0]);
         }
 
-        public Object[] toArray(Object[] arr) {
+        public <T> T[] toArray(T[] arr) {
             // special implementation to handle disappearing entries
-            ArrayList list = new ArrayList();
-            Iterator iterator = iterator();
-            while (iterator.hasNext()) {
-                Entry e = (Entry) iterator.next();
-                list.add(new DefaultMapEntry(e.getKey(), e.getValue()));
+            ArrayList<Map.Entry<K, V>> list = new ArrayList<Map.Entry<K, V>>();
+            for (Map.Entry<K, V> entry : this) {
+                list.add(new DefaultMapEntry<K, V>(entry));
             }
             return list.toArray(arr);
         }
@@ -504,9 +509,9 @@
     /**
      * KeySet implementation.
      */
-    static class ReferenceKeySet extends KeySet {
-        
-        protected ReferenceKeySet(AbstractHashedMap parent) {
+    static class ReferenceKeySet<K> extends KeySet<K> {
+
+        protected ReferenceKeySet(AbstractHashedMap<K, ?> parent) {
             super(parent);
         }
 
@@ -514,11 +519,11 @@
             return toArray(new Object[0]);
         }
 
-        public Object[] toArray(Object[] arr) {
+        public <T> T[] toArray(T[] arr) {
             // special implementation to handle disappearing keys
-            List list = new ArrayList(parent.size());
-            for (Iterator it = iterator(); it.hasNext(); ) {
-                list.add(it.next());
+            List<K> list = new ArrayList<K>(parent.size());
+            for (K key : this) {
+                list.add(key);
             }
             return list.toArray(arr);
         }
@@ -528,9 +533,9 @@
     /**
      * Values implementation.
      */
-    static class ReferenceValues extends Values {
-        
-        protected ReferenceValues(AbstractHashedMap parent) {
+    static class ReferenceValues<V> extends Values<V> {
+
+        protected ReferenceValues(AbstractHashedMap<?, V> parent) {
             super(parent);
         }
 
@@ -538,11 +543,11 @@
             return toArray(new Object[0]);
         }
 
-        public Object[] toArray(Object[] arr) {
+        public <T> T[] toArray(T[] arr) {
             // special implementation to handle disappearing values
-            List list = new ArrayList(parent.size());
-            for (Iterator it = iterator(); it.hasNext(); ) {
-                list.add(it.next());
+            List<V> list = new ArrayList<V>(parent.size());
+            for (V value : this) {
+                list.add(value);
             }
             return list.toArray(arr);
         }
@@ -554,23 +559,23 @@
      * <p>
      * If getKey() or getValue() returns null, it means
      * the mapping is stale and should be removed.
-     * 
+     *
      * @since Commons Collections 3.1
      */
-    protected static class ReferenceEntry extends HashEntry {
+    protected static class ReferenceEntry<K, V> extends HashEntry<K, V> {
         /** The parent map */
-        protected final AbstractReferenceMap parent;
+        protected final AbstractReferenceMap<K, V> parent;
 
         /**
          * Creates a new entry object for the ReferenceMap.
-         * 
+         *
          * @param parent  the parent map
          * @param next  the next entry in the hash bucket
          * @param hashCode  the hash code of the key
          * @param key  the key
          * @param value  the value
          */
-        public ReferenceEntry(AbstractReferenceMap parent, HashEntry next, int hashCode, Object key, Object value) {
+        public ReferenceEntry(AbstractReferenceMap<K, V> parent, HashEntry<K, V> next, int hashCode, K key, V value) {
             super(next, hashCode, null, null);
             this.parent = parent;
             this.key = toReference(parent.keyType, key, hashCode);
@@ -580,33 +585,36 @@
         /**
          * Gets the key from the entry.
          * This method dereferences weak and soft keys and thus may return null.
-         * 
+         *
          * @return the key, which may be null if it was garbage collected
          */
-        public Object getKey() {
-            return (parent.keyType > HARD) ? ((Reference) key).get() : key;
+        @SuppressWarnings("unchecked")
+        public K getKey() {
+            return (K) ((parent.keyType == ReferenceStrength.HARD) ? key : ((Reference<K>) key).get());
         }
 
         /**
          * Gets the value from the entry.
          * This method dereferences weak and soft value and thus may return null.
-         * 
+         *
          * @return the value, which may be null if it was garbage collected
          */
-        public Object getValue() {
-            return (parent.valueType > HARD) ? ((Reference) value).get() : value;
+        @SuppressWarnings("unchecked")
+        public V getValue() {
+            return (V) ((parent.valueType == ReferenceStrength.HARD) ? value : ((Reference<V>) value).get());
         }
 
         /**
          * Sets the value of the entry.
-         * 
+         *
          * @param obj  the object to store
          * @return the previous value
          */
-        public Object setValue(Object obj) {
-            Object old = getValue();
-            if (parent.valueType > HARD) {
-                ((Reference)value).clear();
+        @SuppressWarnings("unchecked")
+        public V setValue(V obj) {
+            V old = getValue();
+            if (parent.valueType != ReferenceStrength.HARD) {
+                ((Reference<V>) value).clear();
             }
             value = toReference(parent.valueType, obj, hashCode);
             return old;
@@ -617,10 +625,11 @@
          * <p>
          * This implementation uses <code>isEqualKey</code> and
          * <code>isEqualValue</code> on the main map for comparison.
-         * 
+         *
          * @param obj  the other map entry to compare to
          * @return true if equal, false if not
          */
+        @SuppressWarnings("unchecked")
         public boolean equals(Object obj) {
             if (obj == this) {
                 return true;
@@ -628,7 +637,7 @@
             if (obj instanceof Map.Entry == false) {
                 return false;
             }
-            
+
             Map.Entry entry = (Map.Entry)obj;
             Object entryKey = entry.getKey();  // convert to hard reference
             Object entryValue = entry.getValue();  // convert to hard reference
@@ -645,7 +654,7 @@
          * Gets the hashcode of the entry using temporary hard references.
          * <p>
          * This implementation uses <code>hashEntry</code> on the main map.
-         * 
+         *
          * @return the hashcode of the entry
          */
         public int hashCode() {
@@ -662,13 +671,17 @@
          *    this number might be different from referent.hashCode() if
          *    the referent represents a value and not a key
          */
-        protected Object toReference(int type, Object referent, int hash) {
-            switch (type) {
-                case HARD: return referent;
-                case SOFT: return new SoftRef(hash, referent, parent.queue);
-                case WEAK: return new WeakRef(hash, referent, parent.queue);
-                default: throw new Error();
+        protected <T> Object toReference(ReferenceStrength type, T referent, int hash) {
+            if (type == ReferenceStrength.HARD) {
+                return referent;
+            }
+            if (type == ReferenceStrength.SOFT) {
+                return new SoftRef<T>(hash, referent, parent.queue);
+            }
+            if (type == ReferenceStrength.WEAK) {
+                return new WeakRef<T>(hash, referent, parent.queue);
             }
+            throw new Error();
         }
 
         /**
@@ -676,15 +689,15 @@
          * @param ref  the reference to purge
          * @return true or false
          */
-        boolean purge(Reference ref) {
-            boolean r = (parent.keyType > HARD) && (key == ref);
-            r = r || ((parent.valueType > HARD) && (value == ref));
+        boolean purge(Reference<?> ref) {
+            boolean r = (parent.keyType != ReferenceStrength.HARD) && (key == ref);
+            r = r || ((parent.valueType != ReferenceStrength.HARD) && (value == ref));
             if (r) {
-                if (parent.keyType > HARD) {
-                    ((Reference)key).clear();
+                if (parent.keyType != ReferenceStrength.HARD) {
+                    ((Reference<?>) key).clear();
                 }
-                if (parent.valueType > HARD) {
-                    ((Reference)value).clear();
+                if (parent.valueType != ReferenceStrength.HARD) {
+                    ((Reference<?>) value).clear();
                 } else if (parent.purgeValues) {
                     value = null;
                 }
@@ -694,36 +707,36 @@
 
         /**
          * Gets the next entry in the bucket.
-         * 
+         *
          * @return the next entry in the bucket
          */
-        protected ReferenceEntry next() {
-            return (ReferenceEntry) next;
+        protected ReferenceEntry<K, V> next() {
+            return (ReferenceEntry<K, V>) next;
         }
     }
 
     //-----------------------------------------------------------------------
     /**
-     * The EntrySet iterator.
+     * Base iterator class.
      */
-    static class ReferenceEntrySetIterator implements Iterator {
+    static class ReferenceBaseIterator<K, V> {
         /** The parent map */
-        final AbstractReferenceMap parent;
-        
+        final AbstractReferenceMap<K, V> parent;
+
         // These fields keep track of where we are in the table.
         int index;
-        ReferenceEntry entry;
-        ReferenceEntry previous;
+        ReferenceEntry<K, V> entry;
+        ReferenceEntry<K, V> previous;
 
         // These Object fields provide hard references to the
         // current and next entry; this assures that if hasNext()
         // returns true, next() will actually return a valid element.
-        Object nextKey, nextValue;
-        Object currentKey, currentValue;
+        K currentKey, nextKey;
+        V currentValue, nextValue;
 
         int expectedModCount;
 
-        public ReferenceEntrySetIterator(AbstractReferenceMap parent) {
+        public ReferenceBaseIterator(AbstractReferenceMap<K, V> parent) {
             super();
             this.parent = parent;
             index = (parent.size() != 0 ? parent.data.length : 0);
@@ -735,11 +748,11 @@
         public boolean hasNext() {
             checkMod();
             while (nextNull()) {
-                ReferenceEntry e = entry;
+                ReferenceEntry<K, V> e = entry;
                 int i = index;
                 while ((e == null) && (i > 0)) {
                     i--;
-                    e = (ReferenceEntry) parent.data[i];
+                    e = (ReferenceEntry<K, V>) parent.data[i];
                 }
                 entry = e;
                 index = i;
@@ -767,7 +780,7 @@
             return (nextKey == null) || (nextValue == null);
         }
 
-        protected ReferenceEntry nextEntry() {    
+        protected ReferenceEntry<K, V> nextEntry() {
             checkMod();
             if (nextNull() && !hasNext()) {
                 throw new NoSuchElementException();
@@ -781,14 +794,10 @@
             return previous;
         }
 
-        protected ReferenceEntry currentEntry() {
+        protected ReferenceEntry<K, V> currentEntry() {
             checkMod();
             return previous;
         }
-        
-        public Object next() {
-            return nextEntry();
-        }
 
         public void remove() {
             checkMod();
@@ -804,15 +813,31 @@
     }
 
     /**
-     * The keySet iterator.
+     * The EntrySet iterator.
      */
-    static class ReferenceKeySetIterator extends ReferenceEntrySetIterator {
-        
-        ReferenceKeySetIterator(AbstractReferenceMap parent) {
+    static class ReferenceEntrySetIterator<K, V> extends ReferenceBaseIterator<K, V> implements Iterator<Map.Entry<K, V>> {
+
+        public ReferenceEntrySetIterator(AbstractReferenceMap<K, V> parent) {
             super(parent);
         }
-        
-        public Object next() {
+
+        public Map.Entry<K, V> next() {
+            return nextEntry();
+        }
+
+    }
+
+    /**
+     * The keySet iterator.
+     */
+    static class ReferenceKeySetIterator<K> extends ReferenceBaseIterator<K, Object> implements Iterator<K> {
+
+        @SuppressWarnings("unchecked")
+        ReferenceKeySetIterator(AbstractReferenceMap<K, ?> parent) {
+            super((AbstractReferenceMap<K, Object>) parent);
+        }
+
+        public K next() {
             return nextEntry().getKey();
         }
     }
@@ -820,13 +845,14 @@
     /**
      * The values iterator.
      */
-    static class ReferenceValuesIterator extends ReferenceEntrySetIterator {
-        
-        ReferenceValuesIterator(AbstractReferenceMap parent) {
-            super(parent);
+    static class ReferenceValuesIterator<V> extends ReferenceBaseIterator<Object, V> implements Iterator<V> {
+
+        @SuppressWarnings("unchecked")
+        ReferenceValuesIterator(AbstractReferenceMap<?, V> parent) {
+            super((AbstractReferenceMap<Object, V>) parent);
         }
-        
-        public Object next() {
+
+        public V next() {
             return nextEntry().getValue();
         }
     }
@@ -834,41 +860,41 @@
     /**
      * The MapIterator implementation.
      */
-    static class ReferenceMapIterator extends ReferenceEntrySetIterator implements MapIterator {
-        
-        protected ReferenceMapIterator(AbstractReferenceMap parent) {
+    static class ReferenceMapIterator<K, V> extends ReferenceBaseIterator<K, V> implements MapIterator<K, V> {
+
+        protected ReferenceMapIterator(AbstractReferenceMap<K, V> parent) {
             super(parent);
         }
 
-        public Object next() {
+        public K next() {
             return 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);
         }
     }
-    
+
     //-----------------------------------------------------------------------
     // These two classes store the hashCode of the key of
     // of the mapping, so that after they're dequeued a quick
@@ -877,11 +903,11 @@
     /**
      * A soft reference holder.
      */
-    static class SoftRef extends SoftReference {
+    static class SoftRef<T> extends SoftReference<T> {
         /** the hashCode of the key (even if the reference points to a value) */
         private int hash;
 
-        public SoftRef(int hash, Object r, ReferenceQueue q) {
+        public SoftRef(int hash, T r, ReferenceQueue<? super T> q) {
             super(r, q);
             this.hash = hash;
         }
@@ -894,11 +920,11 @@
     /**
      * A weak reference holder.
      */
-    static class WeakRef extends WeakReference {
+    static class WeakRef<T> extends WeakReference<T> {
         /** the hashCode of the key (even if the reference points to a value) */
         private int hash;
 
-        public WeakRef(int hash, Object r, ReferenceQueue q) {
+        public WeakRef(int hash, T r, ReferenceQueue<? super T> q) {
             super(r, q);
             this.hash = hash;
         }
@@ -924,16 +950,16 @@
      * 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.writeInt(keyType);
-        out.writeInt(valueType);
+        out.writeInt(keyType.value);
+        out.writeInt(valueType.value);
         out.writeBoolean(purgeValues);
         out.writeFloat(loadFactor);
         out.writeInt(data.length);
-        for (MapIterator it = mapIterator(); it.hasNext();) {
+        for (MapIterator<K, V> it = mapIterator(); it.hasNext();) {
             out.writeObject(it.next());
             out.writeObject(it.getValue());
         }
@@ -955,23 +981,24 @@
      * <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 {
-        this.keyType = in.readInt();
-        this.valueType = in.readInt();
+        this.keyType = ReferenceStrength.resolve(in.readInt());
+        this.valueType = ReferenceStrength.resolve(in.readInt());
         this.purgeValues = in.readBoolean();
         this.loadFactor = in.readFloat();
         int capacity = in.readInt();
         init();
         data = new HashEntry[capacity];
         while (true) {
-            Object key = in.readObject();
+            K key = (K) in.readObject();
             if (key == null) {
                 break;
             }
-            Object value = in.readObject();
+            V value = (V) in.readObject();
             put(key, value);
         }
         threshold = calculateThreshold(data.length, loadFactor);

Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/CaseInsensitiveMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/CaseInsensitiveMap.java?rev=814997&r1=814996&r2=814997&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/CaseInsensitiveMap.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/CaseInsensitiveMap.java Tue Sep 15 05:29:56 2009
@@ -57,7 +57,7 @@
  *
  * @author Commons-Collections team
  */
-public class CaseInsensitiveMap extends AbstractHashedMap implements Serializable, Cloneable {
+public class CaseInsensitiveMap<K, V> extends AbstractHashedMap<K, V> implements Serializable, Cloneable {
 
     /** Serialisation version */
     private static final long serialVersionUID = -7074655917369299456L;
@@ -102,7 +102,7 @@
      * @param map  the map to copy
      * @throws NullPointerException if the map is null
      */
-    public CaseInsensitiveMap(Map map) {
+    public CaseInsensitiveMap(Map<K, V> map) {
         super(map);
     }
 
@@ -123,9 +123,8 @@
                 chars[i] = Character.toLowerCase(Character.toUpperCase(chars[i]));
             }
             return new String(chars);
-        } else {
-            return AbstractHashedMap.NULL;
         }
+        return AbstractHashedMap.NULL;
     }   
 
     //-----------------------------------------------------------------------
@@ -134,8 +133,8 @@
      *
      * @return a shallow clone
      */
-    public Object clone() {
-        return super.clone();
+    public CaseInsensitiveMap<K, V> clone() {
+        return (CaseInsensitiveMap<K, V>) super.clone();
     }
 
     /**

Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/FixedSizeSortedMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/FixedSizeSortedMap.java?rev=814997&r1=814996&r2=814997&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/FixedSizeSortedMap.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/FixedSizeSortedMap.java Tue Sep 15 05:29:56 2009
@@ -21,12 +21,12 @@
 import java.io.ObjectOutputStream;
 import java.io.Serializable;
 import java.util.Collection;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
 import java.util.SortedMap;
 
 import org.apache.commons.collections.BoundedMap;
+import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.collections.collection.UnmodifiableCollection;
 import org.apache.commons.collections.set.UnmodifiableSet;
 
@@ -57,9 +57,9 @@
  * @author Stephen Colebourne
  * @author Paul Jack
  */
-public class FixedSizeSortedMap
-        extends AbstractSortedMapDecorator
-        implements SortedMap, BoundedMap, Serializable {
+public class FixedSizeSortedMap<K, V>
+        extends AbstractSortedMapDecorator<K, V>
+        implements SortedMap<K, V>, BoundedMap<K, V>, Serializable {
 
     /** Serialization version */
     private static final long serialVersionUID = 3126019624511683653L;
@@ -70,8 +70,8 @@
      * @param map  the map to decorate, must not be null
      * @throws IllegalArgumentException if map is null
      */
-    public static SortedMap decorate(SortedMap map) {
-        return new FixedSizeSortedMap(map);
+    public static <K, V> SortedMap<K, V> decorate(SortedMap<K, V> map) {
+        return new FixedSizeSortedMap<K, V>(map);
     }
 
     //-----------------------------------------------------------------------
@@ -81,7 +81,7 @@
      * @param map  the map to decorate, must not be null
      * @throws IllegalArgumentException if map is null
      */
-    protected FixedSizeSortedMap(SortedMap map) {
+    protected FixedSizeSortedMap(SortedMap<K, V> map) {
         super(map);
     }
 
@@ -90,8 +90,8 @@
      * 
      * @return the decorated map
      */
-    protected SortedMap getSortedMap() {
-        return (SortedMap) map;
+    protected SortedMap<K, V> getSortedMap() {
+        return (SortedMap<K, V>) map;
     }
 
     //-----------------------------------------------------------------------
@@ -106,24 +106,23 @@
     /**
      * Read the map in using a custom routine.
      */
+    @SuppressWarnings("unchecked")
     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
         in.defaultReadObject();
         map = (Map) in.readObject();
     }
 
     //-----------------------------------------------------------------------
-    public Object put(Object key, Object value) {
+    public V put(K key, V value) {
         if (map.containsKey(key) == false) {
             throw new IllegalArgumentException("Cannot put new key/value pair - Map is fixed size");
         }
         return map.put(key, value);
     }
 
-    public void putAll(Map mapToCopy) {
-        for (Iterator it = mapToCopy.keySet().iterator(); it.hasNext(); ) {
-            if (mapToCopy.containsKey(it.next()) == false) {
-                throw new IllegalArgumentException("Cannot put new key/value pair - Map is fixed size");
-            }
+    public void putAll(Map<? extends K, ? extends V> mapToCopy) {
+        if (CollectionUtils.isSubCollection(mapToCopy.keySet(), keySet())) {
+            throw new IllegalArgumentException("Cannot put new key/value pair - Map is fixed size");
         }
         map.putAll(mapToCopy);
     }
@@ -132,39 +131,33 @@
         throw new UnsupportedOperationException("Map is fixed size");
     }
 
-    public Object remove(Object key) {
+    public V remove(Object key) {
         throw new UnsupportedOperationException("Map is fixed size");
     }
 
-    public Set entrySet() {
-        Set set = map.entrySet();
-        return UnmodifiableSet.decorate(set);
+    public Set<Map.Entry<K, V>> entrySet() {
+        return UnmodifiableSet.decorate(map.entrySet());
     }
 
-    public Set keySet() {
-        Set set = map.keySet();
-        return UnmodifiableSet.decorate(set);
+    public Set<K> keySet() {
+        return UnmodifiableSet.decorate(map.keySet());
     }
 
-    public Collection values() {
-        Collection coll = map.values();
-        return UnmodifiableCollection.decorate(coll);
+    public Collection<V> values() {
+        return UnmodifiableCollection.decorate(map.values());
     }
 
     //-----------------------------------------------------------------------
-    public SortedMap subMap(Object fromKey, Object toKey) {
-        SortedMap map = getSortedMap().subMap(fromKey, toKey);
-        return new FixedSizeSortedMap(map);
+    public SortedMap<K, V> subMap(K fromKey, K toKey) {
+        return new FixedSizeSortedMap<K, V>(getSortedMap().subMap(fromKey, toKey));
     }
 
-    public SortedMap headMap(Object toKey) {
-        SortedMap map = getSortedMap().headMap(toKey);
-        return new FixedSizeSortedMap(map);
+    public SortedMap<K, V> headMap(K toKey) {
+        return new FixedSizeSortedMap<K, V>(getSortedMap().headMap(toKey));
     }
 
-    public SortedMap tailMap(Object fromKey) {
-        SortedMap map = getSortedMap().tailMap(fromKey);
-        return new FixedSizeSortedMap(map);
+    public SortedMap<K, V> tailMap(K fromKey) {
+        return new FixedSizeSortedMap<K, V>(getSortedMap().tailMap(fromKey));
     }
 
     public boolean isFull() {

Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/Flat3Map.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/Flat3Map.java?rev=814997&r1=814996&r2=814997&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/Flat3Map.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/Flat3Map.java Tue Sep 15 05:29:56 2009
@@ -64,7 +64,7 @@
  * <strong>Note that Flat3Map is not synchronized and is not thread-safe.</strong>
  * If you wish to use this map from multiple threads concurrently, you must use
  * appropriate synchronization. The simplest approach is to wrap this map
- * using {@link java.util.Collections#synchronizedMap(Map)}. This class may throw 
+ * using {@link java.util.Collections#synchronizedMap(Map)}. This class may throw
  * exceptions when accessed by concurrent threads without synchronization.
  *
  * @since Commons Collections 3.0
@@ -72,7 +72,7 @@
  *
  * @author Stephen Colebourne
  */
-public class Flat3Map implements IterableMap, Serializable, Cloneable {
+public class Flat3Map<K, V> implements IterableMap<K, V>, Serializable, Cloneable {
 
     /** Serialization version */
     private static final long serialVersionUID = -6701087419741928296L;
@@ -86,19 +86,19 @@
     /** Hash, used while in flat mode */
     private transient int hash3;
     /** Key, used while in flat mode */
-    private transient Object key1;
+    private transient K key1;
     /** Key, used while in flat mode */
-    private transient Object key2;
+    private transient K key2;
     /** Key, used while in flat mode */
-    private transient Object key3;
+    private transient K key3;
     /** Value, used while in flat mode */
-    private transient Object value1;
+    private transient V value1;
     /** Value, used while in flat mode */
-    private transient Object value2;
+    private transient V value2;
     /** Value, used while in flat mode */
-    private transient Object value3;
+    private transient V value3;
     /** Map, used while in delegate mode */
-    private transient AbstractHashedMap delegateMap;
+    private transient AbstractHashedMap<K, V> delegateMap;
 
     /**
      * Constructor.
@@ -113,7 +113,7 @@
      * @param map  the map to copy
      * @throws NullPointerException if the map is null
      */
-    public Flat3Map(Map map) {
+    public Flat3Map(Map<? extends K, ? extends V> map) {
         super();
         putAll(map);
     }
@@ -121,11 +121,11 @@
     //-----------------------------------------------------------------------
     /**
      * 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) {
         if (delegateMap != null) {
             return delegateMap.get(key);
         }
@@ -158,7 +158,7 @@
 
     /**
      * Gets the size of the map.
-     * 
+     *
      * @return the size
      */
     public int size() {
@@ -170,7 +170,7 @@
 
     /**
      * Checks whether the map is currently empty.
-     * 
+     *
      * @return true if the map is currently size zero
      */
     public boolean isEmpty() {
@@ -180,7 +180,7 @@
     //-----------------------------------------------------------------------
     /**
      * Checks whether the map contains the specified key.
-     * 
+     *
      * @param key  the key to search for
      * @return true if the map contains the key
      */
@@ -215,7 +215,7 @@
 
     /**
      * Checks whether the map contains the specified value.
-     * 
+     *
      * @param value  the value to search for
      * @return true if the map contains the key
      */
@@ -248,12 +248,12 @@
     //-----------------------------------------------------------------------
     /**
      * 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) {
+    public V put(K key, V value) {
         if (delegateMap != null) {
             return delegateMap.put(key, value);
         }
@@ -262,19 +262,19 @@
             switch (size) {  // drop through
                 case 3:
                     if (key3 == null) {
-                        Object old = value3;
+                        V old = value3;
                         value3 = value;
                         return old;
                     }
                 case 2:
                     if (key2 == null) {
-                        Object old = value2;
+                        V old = value2;
                         value2 = value;
                         return old;
                     }
                 case 1:
                     if (key1 == null) {
-                        Object old = value1;
+                        V old = value1;
                         value1 = value;
                         return old;
                     }
@@ -285,26 +285,26 @@
                 switch (size) {  // drop through
                     case 3:
                         if (hash3 == hashCode && key.equals(key3)) {
-                            Object old = value3;
+                            V old = value3;
                             value3 = value;
                             return old;
                         }
                     case 2:
                         if (hash2 == hashCode && key.equals(key2)) {
-                            Object old = value2;
+                            V old = value2;
                             value2 = value;
                             return old;
                         }
                     case 1:
                         if (hash1 == hashCode && key.equals(key1)) {
-                            Object old = value1;
+                            V old = value1;
                             value1 = value;
                             return old;
                         }
                 }
             }
         }
-        
+
         // add new mapping
         switch (size) {
             default:
@@ -333,11 +333,11 @@
 
     /**
      * Puts all the values from the specified map into this map.
-     * 
+     *
      * @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) {
         int size = map.size();
         if (size == 0) {
             return;
@@ -347,8 +347,7 @@
             return;
         }
         if (size < 4) {
-            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());
             }
         } else {
@@ -370,7 +369,7 @@
             case 1:
                 delegateMap.put(key1, value1);
         }
-        
+
         size = 0;
         hash1 = hash2 = hash3 = 0;
         key1 = key2 = key3 = null;
@@ -387,17 +386,17 @@
      * @return a new AbstractHashedMap or subclass
      * @since Commons Collections 3.1
      */
-    protected AbstractHashedMap createDelegateMap() {
-        return new HashedMap();
+    protected AbstractHashedMap<K, V> createDelegateMap() {
+        return new HashedMap<K, V>();
     }
 
     /**
      * 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) {
         if (delegateMap != null) {
             return delegateMap.remove(key);
         }
@@ -408,7 +407,7 @@
             switch (size) {  // drop through
                 case 3:
                     if (key3 == null) {
-                        Object old = value3;
+                        V old = value3;
                         hash3 = 0;
                         key3 = null;
                         value3 = null;
@@ -416,7 +415,7 @@
                         return old;
                     }
                     if (key2 == null) {
-                        Object old = value2;
+                        V old = value2;
                         hash2 = hash3;
                         key2 = key3;
                         value2 = value3;
@@ -427,7 +426,7 @@
                         return old;
                     }
                     if (key1 == null) {
-                        Object old = value1;
+                        V old = value1;
                         hash1 = hash3;
                         key1 = key3;
                         value1 = value3;
@@ -440,7 +439,7 @@
                     return null;
                 case 2:
                     if (key2 == null) {
-                        Object old = value2;
+                        V old = value2;
                         hash2 = 0;
                         key2 = null;
                         value2 = null;
@@ -448,7 +447,7 @@
                         return old;
                     }
                     if (key1 == null) {
-                        Object old = value1;
+                        V old = value1;
                         hash1 = hash2;
                         key1 = key2;
                         value1 = value2;
@@ -461,7 +460,7 @@
                     return null;
                 case 1:
                     if (key1 == null) {
-                        Object old = value1;
+                        V old = value1;
                         hash1 = 0;
                         key1 = null;
                         value1 = null;
@@ -475,7 +474,7 @@
                 switch (size) {  // drop through
                     case 3:
                         if (hash3 == hashCode && key.equals(key3)) {
-                            Object old = value3;
+                            V old = value3;
                             hash3 = 0;
                             key3 = null;
                             value3 = null;
@@ -483,7 +482,7 @@
                             return old;
                         }
                         if (hash2 == hashCode && key.equals(key2)) {
-                            Object old = value2;
+                            V old = value2;
                             hash2 = hash3;
                             key2 = key3;
                             value2 = value3;
@@ -494,7 +493,7 @@
                             return old;
                         }
                         if (hash1 == hashCode && key.equals(key1)) {
-                            Object old = value1;
+                            V old = value1;
                             hash1 = hash3;
                             key1 = key3;
                             value1 = value3;
@@ -507,7 +506,7 @@
                         return null;
                     case 2:
                         if (hash2 == hashCode && key.equals(key2)) {
-                            Object old = value2;
+                            V old = value2;
                             hash2 = 0;
                             key2 = null;
                             value2 = null;
@@ -515,7 +514,7 @@
                             return old;
                         }
                         if (hash1 == hashCode && key.equals(key1)) {
-                            Object old = value1;
+                            V old = value1;
                             hash1 = hash2;
                             key1 = key2;
                             value1 = value2;
@@ -528,7 +527,7 @@
                         return null;
                     case 1:
                         if (hash1 == hashCode && key.equals(key1)) {
-                            Object old = value1;
+                            V old = value1;
                             hash1 = 0;
                             key1 = null;
                             value1 = null;
@@ -566,28 +565,28 @@
      * 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 (delegateMap != null) {
             return delegateMap.mapIterator();
         }
         if (size == 0) {
-            return EmptyMapIterator.INSTANCE;
+            return EmptyMapIterator.<K, V>getInstance();
         }
-        return new FlatMapIterator(this);
+        return new FlatMapIterator<K, V>(this);
     }
 
     /**
      * FlatMapIterator
      */
-    static class FlatMapIterator implements MapIterator, ResettableIterator {
-        private final Flat3Map parent;
+    static class FlatMapIterator<K, V> implements MapIterator<K, V>, ResettableIterator<K> {
+        private final Flat3Map<K, V> parent;
         private int nextIndex = 0;
         private boolean canRemove = false;
-        
-        FlatMapIterator(Flat3Map parent) {
+
+        FlatMapIterator(Flat3Map<K, V> parent) {
             super();
             this.parent = parent;
         }
@@ -596,7 +595,7 @@
             return (nextIndex < parent.size);
         }
 
-        public Object next() {
+        public K next() {
             if (hasNext() == false) {
                 throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY);
             }
@@ -614,7 +613,7 @@
             canRemove = false;
         }
 
-        public Object getKey() {
+        public K getKey() {
             if (canRemove == false) {
                 throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
             }
@@ -629,7 +628,7 @@
             throw new IllegalStateException("Invalid map index");
         }
 
-        public Object getValue() {
+        public V getValue() {
             if (canRemove == false) {
                 throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
             }
@@ -644,13 +643,13 @@
             throw new IllegalStateException("Invalid map index");
         }
 
-        public Object setValue(Object value) {
+        public V setValue(V value) {
             if (canRemove == false) {
                 throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
             }
-            Object old = getValue();
+            V old = getValue();
             switch (nextIndex) {
-                case 3: 
+                case 3:
                     parent.value3 = value;
                     break;
                 case 2:
@@ -662,44 +661,43 @@
             }
             return old;
         }
-        
+
         public void reset() {
             nextIndex = 0;
             canRemove = false;
         }
-        
+
         public String toString() {
             if (canRemove) {
                 return "Iterator[" + getKey() + "=" + getValue() + "]";
-            } else {
-                return "Iterator[]";
             }
+            return "Iterator[]";
         }
     }
-    
+
     /**
      * Gets the entrySet view of the map.
      * Changes made to the view affect this map.
-     * The Map Entry is not an independent object and changes as the 
+     * The Map Entry is not an independent object and changes as the
      * iterator progresses.
      * To simply iterate through the entries, use {@link #mapIterator()}.
-     * 
+     *
      * @return the entrySet view
      */
-    public Set entrySet() {
+    public Set<Map.Entry<K, V>> entrySet() {
         if (delegateMap != null) {
             return delegateMap.entrySet();
         }
-        return new EntrySet(this);
+        return new EntrySet<K, V>(this);
     }
-    
+
     /**
      * EntrySet
      */
-    static class EntrySet extends AbstractSet {
-        private final Flat3Map parent;
-        
-        EntrySet(Flat3Map parent) {
+    static class EntrySet<K, V> extends AbstractSet<Map.Entry<K, V>> {
+        private final Flat3Map<K, V> parent;
+
+        EntrySet(Flat3Map<K, V> parent) {
             super();
             this.parent = parent;
         }
@@ -707,43 +705,42 @@
         public int size() {
             return parent.size();
         }
-        
+
         public void clear() {
             parent.clear();
         }
-        
+
         public boolean remove(Object obj) {
             if (obj instanceof Map.Entry == false) {
                 return false;
             }
-            Map.Entry entry = (Map.Entry) obj;
+            Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj;
             Object key = entry.getKey();
             boolean result = parent.containsKey(key);
             parent.remove(key);
             return result;
         }
 
-        public Iterator iterator() {
+        public Iterator<Map.Entry<K, V>> iterator() {
             if (parent.delegateMap != null) {
                 return parent.delegateMap.entrySet().iterator();
             }
             if (parent.size() == 0) {
-                return EmptyIterator.INSTANCE;
+                return EmptyIterator.<Map.Entry<K, V>>getInstance();
             }
-            return new EntrySetIterator(parent);
+            return new EntrySetIterator<K, V>(parent);
         }
     }
 
-    /**
-     * EntrySetIterator and MapEntry
-     */
-    static class EntrySetIterator implements Iterator, Map.Entry {
-        private final Flat3Map parent;
+    static abstract class EntryIterator<K, V> implements Map.Entry<K, V> {
+        private final Flat3Map<K, V> parent;
         private int nextIndex = 0;
-        private boolean canRemove = false;
-        
-        EntrySetIterator(Flat3Map parent) {
-            super();
+        protected boolean canRemove = false;
+
+        /**
+         * Create a new Flat3Map.EntryIterator.
+         */
+        public EntryIterator(Flat3Map<K, V> parent) {
             this.parent = parent;
         }
 
@@ -751,7 +748,7 @@
             return (nextIndex < parent.size);
         }
 
-        public Object next() {
+        public Map.Entry<K, V> nextEntry() {
             if (hasNext() == false) {
                 throw new NoSuchElementException(AbstractHashedMap.NO_NEXT_ENTRY);
             }
@@ -769,7 +766,7 @@
             canRemove = false;
         }
 
-        public Object getKey() {
+        public K getKey() {
             if (canRemove == false) {
                 throw new IllegalStateException(AbstractHashedMap.GETKEY_INVALID);
             }
@@ -784,7 +781,7 @@
             throw new IllegalStateException("Invalid map index");
         }
 
-        public Object getValue() {
+        public V getValue() {
             if (canRemove == false) {
                 throw new IllegalStateException(AbstractHashedMap.GETVALUE_INVALID);
             }
@@ -799,13 +796,13 @@
             throw new IllegalStateException("Invalid map index");
         }
 
-        public Object setValue(Object value) {
+        public V setValue(V value) {
             if (canRemove == false) {
                 throw new IllegalStateException(AbstractHashedMap.SETVALUE_INVALID);
             }
-            Object old = getValue();
+            V old = getValue();
             switch (nextIndex) {
-                case 3: 
+                case 3:
                     parent.value3 = value;
                     break;
                 case 2:
@@ -817,7 +814,21 @@
             }
             return old;
         }
-        
+    }
+
+    /**
+     * EntrySetIterator and MapEntry
+     */
+    static class EntrySetIterator<K, V> extends EntryIterator<K, V> implements Iterator<Map.Entry<K, V>> {
+
+        EntrySetIterator(Flat3Map<K, V> parent) {
+            super(parent);
+        }
+
+        public Map.Entry<K, V> next() {
+            return nextEntry();
+        }
+
         public boolean equals(Object obj) {
             if (canRemove == false) {
                 return false;
@@ -825,13 +836,13 @@
             if (obj instanceof Map.Entry == false) {
                 return false;
             }
-            Map.Entry other = (Map.Entry) obj;
+            Map.Entry<?, ?> other = (Map.Entry<?, ?>) obj;
             Object key = getKey();
             Object value = getValue();
             return (key == null ? other.getKey() == null : key.equals(other.getKey())) &&
                    (value == null ? other.getValue() == null : value.equals(other.getValue()));
         }
-        
+
         public int hashCode() {
             if (canRemove == false) {
                 return 0;
@@ -841,37 +852,36 @@
             return (key == null ? 0 : key.hashCode()) ^
                    (value == null ? 0 : value.hashCode());
         }
-        
+
         public String toString() {
             if (canRemove) {
                 return getKey() + "=" + getValue();
-            } else {
-                return "";
             }
+            return "";
         }
     }
-    
+
     /**
      * 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 (delegateMap != null) {
             return delegateMap.keySet();
         }
-        return new KeySet(this);
+        return new KeySet<K>(this);
     }
 
     /**
      * KeySet
      */
-    static class KeySet extends AbstractSet {
-        private final Flat3Map parent;
-        
-        KeySet(Flat3Map parent) {
+    static class KeySet<K> extends AbstractSet<K> {
+        private final Flat3Map<K, ?> parent;
+
+        KeySet(Flat3Map<K, ?> parent) {
             super();
             this.parent = parent;
         }
@@ -879,11 +889,11 @@
         public int size() {
             return parent.size();
         }
-        
+
         public void clear() {
             parent.clear();
         }
-        
+
         public boolean contains(Object key) {
             return parent.containsKey(key);
         }
@@ -894,53 +904,54 @@
             return result;
         }
 
-        public Iterator iterator() {
+        public Iterator<K> iterator() {
             if (parent.delegateMap != null) {
                 return parent.delegateMap.keySet().iterator();
             }
             if (parent.size() == 0) {
-                return EmptyIterator.INSTANCE;
+                return EmptyIterator.<K>getInstance();
             }
-            return new KeySetIterator(parent);
+            return new KeySetIterator<K>(parent);
         }
     }
 
     /**
      * KeySetIterator
      */
-    static class KeySetIterator extends EntrySetIterator {
-        
-        KeySetIterator(Flat3Map parent) {
-            super(parent);
+    static class KeySetIterator<K> extends EntryIterator<K, Object> implements Iterator<K>{
+
+        @SuppressWarnings("unchecked")
+        KeySetIterator(Flat3Map<K, ?> parent) {
+            super((Flat3Map<K, Object>) parent);
         }
 
-        public Object next() {
-            super.next();
+        public K next() {
+            nextEntry();
             return 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 (delegateMap != null) {
             return delegateMap.values();
         }
-        return new Values(this);
+        return new Values<V>(this);
     }
 
     /**
      * Values
      */
-    static class Values extends AbstractCollection {
-        private final Flat3Map parent;
-        
-        Values(Flat3Map parent) {
+    static class Values<V> extends AbstractCollection<V> {
+        private final Flat3Map<?, V> parent;
+
+        Values(Flat3Map<?, V> parent) {
             super();
             this.parent = parent;
         }
@@ -948,37 +959,38 @@
         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() {
             if (parent.delegateMap != null) {
                 return parent.delegateMap.values().iterator();
             }
             if (parent.size() == 0) {
-                return EmptyIterator.INSTANCE;
+                return EmptyIterator.<V>getInstance();
             }
-            return new ValuesIterator(parent);
+            return new ValuesIterator<V>(parent);
         }
     }
 
     /**
      * ValuesIterator
      */
-    static class ValuesIterator extends EntrySetIterator {
-        
-        ValuesIterator(Flat3Map parent) {
-            super(parent);
+    static class ValuesIterator<V> extends EntryIterator<Object, V> implements Iterator<V> {
+
+        @SuppressWarnings("unchecked")
+        ValuesIterator(Flat3Map<?, V> parent) {
+            super((Flat3Map<Object, V>) parent);
         }
 
-        public Object next() {
-            super.next();
+        public V next() {
+            nextEntry();
             return getValue();
         }
     }
@@ -990,7 +1002,7 @@
     private void writeObject(ObjectOutputStream out) throws IOException {
         out.defaultWriteObject();
         out.writeInt(size());
-        for (MapIterator it = mapIterator(); it.hasNext();) {
+        for (MapIterator<?, ?> it = mapIterator(); it.hasNext();) {
             out.writeObject(it.next());  // key
             out.writeObject(it.getValue());  // value
         }
@@ -999,6 +1011,7 @@
     /**
      * Read the map in using a custom routine.
      */
+    @SuppressWarnings("unchecked")
     private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
         in.defaultReadObject();
         int count = in.readInt();
@@ -1006,7 +1019,7 @@
             delegateMap = createDelegateMap();
         }
         for (int i = count; i > 0; i--) {
-            put(in.readObject(), in.readObject());
+            put((K) in.readObject(), (V) in.readObject());
         }
     }
 
@@ -1017,11 +1030,12 @@
      * @return a shallow clone
      * @since Commons Collections 3.1
      */
-    public Object clone() {
+    @SuppressWarnings("unchecked")
+    public Flat3Map<K, V> clone() {
         try {
-            Flat3Map cloned = (Flat3Map) super.clone();
+            Flat3Map<K, V> cloned = (Flat3Map<K, V>) super.clone();
             if (cloned.delegateMap != null) {
-                cloned.delegateMap = (HashedMap) cloned.delegateMap.clone();
+                cloned.delegateMap = (HashedMap<K, V>) cloned.delegateMap.clone();
             }
             return cloned;
         } catch (CloneNotSupportedException ex) {
@@ -1031,7 +1045,7 @@
 
     /**
      * Compares this map with another.
-     * 
+     *
      * @param obj  the object to compare to
      * @return true if equal
      */
@@ -1045,7 +1059,7 @@
         if (obj instanceof Map == false) {
             return false;
         }
-        Map other = (Map) obj;
+        Map<?, ?> other = (Map<?, ?>) obj;
         if (size != other.size()) {
             return false;
         }
@@ -1083,7 +1097,7 @@
 
     /**
      * Gets the standard Map hashCode.
-     * 
+     *
      * @return the hash code defined in the Map interface
      */
     public int hashCode() {
@@ -1104,7 +1118,7 @@
 
     /**
      * Gets the map as a String.
-     * 
+     *
      * @return a string version of the map
      */
     public String toString() {

Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/HashedMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/HashedMap.java?rev=814997&r1=814996&r2=814997&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/HashedMap.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/HashedMap.java Tue Sep 15 05:29:56 2009
@@ -26,14 +26,14 @@
  * A <code>Map</code> implementation that is a general purpose alternative
  * to <code>HashMap</code>.
  * <p>
- * This implementation improves on the JDK1.4 HashMap by adding the 
+ * This implementation improves on the JDK1.4 HashMap by adding the
  * {@link org.apache.commons.collections.MapIterator MapIterator}
  * functionality and many methods for subclassing.
  * <p>
  * <strong>Note that HashedMap is not synchronized and is not thread-safe.</strong>
  * If you wish to use this map from multiple threads concurrently, you must use
  * appropriate synchronization. The simplest approach is to wrap this map
- * using {@link java.util.Collections#synchronizedMap(Map)}. This class may throw 
+ * using {@link java.util.Collections#synchronizedMap(Map)}. This class may throw
  * exceptions when accessed by concurrent threads without synchronization.
  *
  * @since Commons Collections 3.0
@@ -41,12 +41,12 @@
  *
  * @author Stephen Colebourne
  */
-public class HashedMap
-        extends AbstractHashedMap implements Serializable, Cloneable {
+public class HashedMap<K, V>
+        extends AbstractHashedMap<K, V> implements Serializable, Cloneable {
 
     /** Serialisation version */
     private static final long serialVersionUID = -1788199231038721040L;
-    
+
     /**
      * Constructs a new empty map with default size and load factor.
      */
@@ -55,7 +55,7 @@
     }
 
     /**
-     * Constructs a new, empty map with the specified initial capacity. 
+     * Constructs a new, empty map with the specified initial capacity.
      *
      * @param initialCapacity  the initial capacity
      * @throws IllegalArgumentException if the initial capacity is less than one
@@ -66,7 +66,7 @@
 
     /**
      * 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
@@ -83,7 +83,7 @@
      * @param map  the map to copy
      * @throws NullPointerException if the map is null
      */
-    public HashedMap(Map map) {
+    public HashedMap(Map<K, V> map) {
         super(map);
     }
 
@@ -93,10 +93,10 @@
      *
      * @return a shallow clone
      */
-    public Object clone() {
-        return super.clone();
+    public HashedMap<K, V> clone() {
+        return (HashedMap<K, V>) super.clone();
     }
-    
+
     /**
      * Write the map out using a custom routine.
      */
@@ -112,5 +112,5 @@
         in.defaultReadObject();
         doReadObject(in);
     }
-    
+
 }

Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/IdentityMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/IdentityMap.java?rev=814997&r1=814996&r2=814997&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/IdentityMap.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/IdentityMap.java Tue Sep 15 05:29:56 2009
@@ -32,7 +32,7 @@
  * <strong>Note that IdentityMap is not synchronized and is not thread-safe.</strong>
  * If you wish to use this map from multiple threads concurrently, you must use
  * appropriate synchronization. The simplest approach is to wrap this map
- * using {@link java.util.Collections#synchronizedMap(Map)}. This class may throw 
+ * using {@link java.util.Collections#synchronizedMap(Map)}. This class may throw
  * exceptions when accessed by concurrent threads without synchronization.
  *
  * @since Commons Collections 3.0
@@ -41,8 +41,8 @@
  * @author java util HashMap
  * @author Stephen Colebourne
  */
-public class IdentityMap
-        extends AbstractHashedMap implements Serializable, Cloneable {
+public class IdentityMap<K, V>
+        extends AbstractHashedMap<K, V> implements Serializable, Cloneable {
 
     /** Serialisation version */
     private static final long serialVersionUID = 2028493495224302329L;
@@ -55,7 +55,7 @@
     }
 
     /**
-     * Constructs a new, empty map with the specified initial capacity. 
+     * Constructs a new, empty map with the specified initial capacity.
      *
      * @param initialCapacity  the initial capacity
      * @throws IllegalArgumentException if the initial capacity is less than one
@@ -66,7 +66,7 @@
 
     /**
      * 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
@@ -83,7 +83,7 @@
      * @param map  the map to copy
      * @throws NullPointerException if the map is null
      */
-    public IdentityMap(Map map) {
+    public IdentityMap(Map<K, V> map) {
         super(map);
     }
 
@@ -91,18 +91,18 @@
     /**
      * Gets the hash code for the key specified.
      * This implementation uses the identity hash code.
-     * 
+     *
      * @param key  the key to get a hash code for
      * @return the hash code
      */
     protected int hash(Object key) {
         return System.identityHashCode(key);
     }
-    
+
     /**
      * Compares two keys for equals.
      * This implementation uses <code>==</code>.
-     * 
+     *
      * @param key1  the first key to compare
      * @param key2  the second key to compare
      * @return true if equal by identity
@@ -110,11 +110,11 @@
     protected boolean isEqualKey(Object key1, Object key2) {
         return (key1 == key2);
     }
-    
+
     /**
      * Compares two values for equals.
      * This implementation uses <code>==</code>.
-     * 
+     *
      * @param value1  the first value to compare
      * @param value2  the second value to compare
      * @return true if equal by identity
@@ -122,31 +122,31 @@
     protected boolean isEqualValue(Object value1, Object value2) {
         return (value1 == value2);
     }
-    
+
     /**
      * Creates an entry to store the data.
      * This implementation creates an IdentityEntry instance.
-     * 
+     *
      * @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 IdentityEntry(next, hashCode, key, value);
+    protected IdentityEntry<K, V> createEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
+        return new IdentityEntry<K, V>(next, hashCode, key, value);
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * HashEntry
      */
-    protected static class IdentityEntry extends HashEntry {
-        
-        protected IdentityEntry(HashEntry next, int hashCode, Object key, Object value) {
+    protected static class IdentityEntry<K, V> extends HashEntry<K, V> {
+
+        protected IdentityEntry(HashEntry<K, V> next, int hashCode, K key, V value) {
             super(next, hashCode, key, value);
         }
-        
+
         public boolean equals(Object obj) {
             if (obj == this) {
                 return true;
@@ -154,28 +154,28 @@
             if (obj instanceof Map.Entry == false) {
                 return false;
             }
-            Map.Entry other = (Map.Entry) obj;
+            Map.Entry<?, ?> other = (Map.Entry<?, ?>) obj;
             return
                 (getKey() == other.getKey()) &&
                 (getValue() == other.getValue());
         }
-        
+
         public int hashCode() {
             return System.identityHashCode(getKey()) ^
                    System.identityHashCode(getValue());
         }
     }
-    
+
     //-----------------------------------------------------------------------
     /**
      * Clones the map without cloning the keys or values.
      *
      * @return a shallow clone
      */
-    public Object clone() {
-        return super.clone();
+    public IdentityMap<K, V> clone() {
+        return (IdentityMap<K, V>) super.clone();
     }
-    
+
     /**
      * Write the map out using a custom routine.
      */
@@ -191,5 +191,5 @@
         in.defaultReadObject();
         doReadObject(in);
     }
-    
+
 }

Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/LRUMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/LRUMap.java?rev=814997&r1=814996&r2=814997&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/LRUMap.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/map/LRUMap.java Tue Sep 15 05:29:56 2009
@@ -35,7 +35,7 @@
  * <p>
  * The map implements <code>OrderedMap</code> and entries may be queried using
  * the bidirectional <code>OrderedMapIterator</code>. The order returned is
- * least recently used to most recently used. Iterators from map views can 
+ * least recently used to most recently used. Iterators from map views can
  * also be cast to <code>OrderedIterator</code> if required.
  * <p>
  * All the available iterators can be reset back to the start by casting to
@@ -44,7 +44,7 @@
  * <strong>Note that LRUMap is not synchronized and is not thread-safe.</strong>
  * If you wish to use this map from multiple threads concurrently, you must use
  * appropriate synchronization. The simplest approach is to wrap this map
- * using {@link java.util.Collections#synchronizedMap(Map)}. This class may throw 
+ * using {@link java.util.Collections#synchronizedMap(Map)}. This class may throw
  * <code>NullPointerException</code>'s when accessed by concurrent threads.
  *
  * @since Commons Collections 3.0 (previously in main package v1.0)
@@ -56,14 +56,14 @@
  * @author Mike Pettypiece
  * @author Mario Ivankovits
  */
-public class LRUMap
-        extends AbstractLinkedMap implements BoundedMap, Serializable, Cloneable {
-    
+public class LRUMap<K, V>
+        extends AbstractLinkedMap<K, V> implements BoundedMap<K, V>, Serializable, Cloneable {
+
     /** Serialisation version */
     private static final long serialVersionUID = -612114643488955218L;
     /** Default maximum size */
     protected static final int DEFAULT_MAX_SIZE = 100;
-    
+
     /** Maximum size */
     private transient int maxSize;
     /** Scan behaviour */
@@ -100,7 +100,7 @@
 
     /**
      * Constructs a new, empty map with the specified initial capacity and
-     * load factor. 
+     * load factor.
      *
      * @param maxSize  the maximum size of the map
      * @param loadFactor  the load factor
@@ -140,7 +140,7 @@
      * @throws NullPointerException if the map is null
      * @throws IllegalArgumentException if the map is empty
      */
-    public LRUMap(Map map) {
+    public LRUMap(Map<K, V> map) {
         this(map, false);
     }
 
@@ -155,7 +155,7 @@
      * @throws IllegalArgumentException if the map is empty
      * @since Commons Collections 3.1
      */
-    public LRUMap(Map map, boolean scanUntilRemovable) {
+    public LRUMap(Map<K, V> map, boolean scanUntilRemovable) {
         this(map.size(), DEFAULT_LOAD_FACTOR, scanUntilRemovable);
         putAll(map);
     }
@@ -166,12 +166,12 @@
      * <p>
      * This operation changes the position of the key in the map to the
      * most recently used position (first).
-     * 
+     *
      * @param key  the key
      * @return the mapped value, null if no match
      */
-    public Object get(Object key) {
-        LinkEntry entry = (LinkEntry) getEntry(key);
+    public V get(Object key) {
+        LinkEntry<K, V> entry = getEntry(key);
         if (entry == null) {
             return null;
         }
@@ -184,10 +184,10 @@
      * Moves an entry to the MRU position at the end of the list.
      * <p>
      * This implementation moves the updated entry to the end of the list.
-     * 
+     *
      * @param entry  the entry to update
      */
-    protected void moveToMRU(LinkEntry entry) {
+    protected void moveToMRU(LinkEntry<K, V> entry) {
         if (entry.after != header) {
             modCount++;
             // remove
@@ -208,21 +208,21 @@
                 " (please report this to dev@commons.apache.org)");
         }
     }
-    
+
     /**
      * Updates an existing key-value mapping.
      * <p>
      * This implementation moves the updated entry to the top of the list
      * using {@link #moveToMRU(AbstractLinkedMap.LinkEntry)}.
-     * 
+     *
      * @param entry  the entry to update
      * @param newValue  the new value to store
      */
-    protected void updateEntry(HashEntry entry, Object newValue) {
-        moveToMRU((LinkEntry) entry);  // handles modCount
+    protected void updateEntry(HashEntry<K, V> entry, V newValue) {
+        moveToMRU((LinkEntry<K, V>) entry);  // handles modCount
         entry.setValue(newValue);
     }
-    
+
     /**
      * Adds a new key-value mapping into this map.
      * <p>
@@ -232,15 +232,15 @@
      * From Commons Collections 3.1 this method uses {@link #isFull()} rather
      * than accessing <code>size</code> and <code>maxSize</code> directly.
      * It also handles the scanUntilRemovable functionality.
-     * 
+     *
      * @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) {
         if (isFull()) {
-            LinkEntry reuse = header.after;
+            LinkEntry<K, V> reuse = header.after;
             boolean removeLRUEntry = false;
             if (scanUntilRemovable) {
                 while (reuse != header && reuse != null) {
@@ -260,7 +260,7 @@
             } else {
                 removeLRUEntry = removeLRU(reuse);
             }
-            
+
             if (removeLRUEntry) {
                 if (reuse == null) {
                     throw new IllegalStateException(
@@ -277,27 +277,27 @@
             super.addMapping(hashIndex, hashCode, key, value);
         }
     }
-    
+
     /**
      * Reuses an entry by removing it and moving it to a new place in the map.
      * <p>
      * This method uses {@link #removeEntry}, {@link #reuseEntry} and {@link #addEntry}.
-     * 
+     *
      * @param entry  the entry to reuse
      * @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 reuseMapping(LinkEntry entry, int hashIndex, int hashCode, Object key, Object value) {
+    protected void reuseMapping(LinkEntry<K, V> entry, int hashIndex, int hashCode, K key, V value) {
         // find the entry before the entry specified in the hash table
         // remember that the parameters (except the first) refer to the new entry,
         // not the old one
         try {
             int removeIndex = hashIndex(entry.hashCode, data.length);
-            HashEntry[] tmp = data;  // may protect against some sync issues
-            HashEntry loop = tmp[removeIndex];
-            HashEntry previous = null;
+            HashEntry<K, V>[] tmp = data;  // may protect against some sync issues
+            HashEntry<K, V> loop = tmp[removeIndex];
+            HashEntry<K, V> previous = null;
             while (loop != entry && loop != null) {
                 previous = loop;
                 loop = loop.next;
@@ -309,7 +309,7 @@
                     " Please check that your keys are immutable, and that you have used synchronization properly." +
                     " If so, then please report this to dev@commons.apache.org as a bug.");
             }
-            
+
             // reuse the entry
             modCount++;
             removeEntry(entry, removeIndex, previous);
@@ -323,7 +323,7 @@
                     " If so, then please report this to dev@commons.apache.org as a bug.");
         }
     }
-    
+
     /**
      * Subclass method to control removal of the least recently used entry from the map.
      * <p>
@@ -354,10 +354,10 @@
      * <p>
      * NOTE: Commons Collections 3.0 passed the wrong entry to this method.
      * This is fixed in version 3.1 onwards.
-     * 
+     *
      * @param entry  the entry to be removed
      */
-    protected boolean removeLRU(LinkEntry entry) {
+    protected boolean removeLRU(LinkEntry<K, V> entry) {
         return true;
     }
 
@@ -397,10 +397,10 @@
      *
      * @return a shallow clone
      */
-    public Object clone() {
-        return super.clone();
+    public LRUMap<K, V> clone() {
+        return (LRUMap<K, V>) super.clone();
     }
-    
+
     /**
      * Write the map out using a custom routine.
      */
@@ -416,7 +416,7 @@
         in.defaultReadObject();
         doReadObject(in);
     }
-    
+
     /**
      * Writes the data necessary for <code>put()</code> to work in deserialization.
      */
@@ -432,5 +432,5 @@
         maxSize = in.readInt();
         super.doReadObject(in);
     }
-    
+
 }



Mime
View raw message