Modified: 
commons/proper/collections/branches/collections_jdk5_branch/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java
URL: 
http://svn.apache.org/viewvc/commons/proper/collections/branches/collections_jdk5_branch/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java?rev=738956&r1=738955&r2=738956&view=diff
==============================================================================
--- 
commons/proper/collections/branches/collections_jdk5_branch/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java
 (original)
+++ 
commons/proper/collections/branches/collections_jdk5_branch/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java
 Thu Jan 29 18:48:37 2009
@@ -5,9 +5,9 @@
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * 
+ *
  *      http://www.apache.org/licenses/LICENSE-2.0
- * 
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -48,97 +48,110 @@
  * <p>
  * NOTE: From Commons Collections 3.1, all subclasses will use 
<code>TreeMap</code>
  * and the flawed <code>createMap</code> method is ignored.
- * 
+ *
  * @since Commons Collections 3.0
  * @version $Id$
- * 
+ *
  * @author Matthew Hawthorne
  * @author Stephen Colebourne
  */
-public class DualTreeBidiMap
-        extends AbstractDualBidiMap implements SortedBidiMap, Serializable {
+public class DualTreeBidiMap<K, V> extends AbstractDualBidiMap<K, V> implements
+        SortedBidiMap<K, V>, Serializable {
 
     /** Ensure serialization compatibility */
     private static final long serialVersionUID = 721969328361809L;
-    /** The comparator to use */
-    protected final Comparator comparator;
+
+    /** The key comparator to use */
+    protected final Comparator<? super K> comparator;
+
+    /** The value comparator to use */
+    protected final Comparator<? super V> valueComparator;
     
     /**
      * Creates an empty <code>DualTreeBidiMap</code>
      */
     public DualTreeBidiMap() {
-        super(new TreeMap(), new TreeMap());
+        super(new TreeMap<K, V>(), new TreeMap<V, K>());
         this.comparator = null;
+        this.valueComparator = null;
     }
 
-    /** 
+    /**
      * Constructs a <code>DualTreeBidiMap</code> and copies the mappings from
-     * specified <code>Map</code>.  
+     * specified <code>Map</code>.
      *
      * @param map  the map whose mappings are to be placed in this map
      */
-    public DualTreeBidiMap(Map map) {
-        super(new TreeMap(), new TreeMap());
+    public DualTreeBidiMap(Map<K, V> map) {
+        super(new TreeMap<K, V>(), new TreeMap<V, K>());
         putAll(map);
         this.comparator = null;
+        this.valueComparator = null;
     }
 
-    /** 
+    /**
      * Constructs a <code>DualTreeBidiMap</code> using the specified 
Comparator.
      *
-     * @param comparator  the Comparator
+     * @param keyComparator  the Comparator
      */
-    public DualTreeBidiMap(Comparator comparator) {
-        super(new TreeMap(comparator), new TreeMap(comparator));
-        this.comparator = comparator;
+    public DualTreeBidiMap(Comparator<? super K> keyComparator, Comparator<? 
super V> valueComparator) {
+        super(new TreeMap<K, V>(keyComparator), new TreeMap<V, 
K>(valueComparator));
+        this.comparator = keyComparator;
+        this.valueComparator = valueComparator;
     }
 
-    /** 
+    /**
      * Constructs a <code>DualTreeBidiMap</code> that decorates the specified 
maps.
      *
      * @param normalMap  the normal direction map
      * @param reverseMap  the reverse direction map
      * @param inverseBidiMap  the inverse BidiMap
      */
-    protected DualTreeBidiMap(Map normalMap, Map reverseMap, BidiMap 
inverseBidiMap) {
+    protected DualTreeBidiMap(Map<K, V> normalMap, Map<V, K> reverseMap, 
BidiMap<V, K> inverseBidiMap) {
         super(normalMap, reverseMap, inverseBidiMap);
-        this.comparator = ((SortedMap) normalMap).comparator();
+        this.comparator = ((SortedMap<K, V>) normalMap).comparator();
+        this.valueComparator = ((SortedMap<V, K>) reverseMap).comparator();
     }
 
     /**
      * Creates a new instance of this object.
-     * 
+     *
      * @param normalMap  the normal direction map
      * @param reverseMap  the reverse direction map
      * @param inverseMap  the inverse BidiMap
      * @return new bidi map
      */
-    protected BidiMap createBidiMap(Map normalMap, Map reverseMap, BidiMap 
inverseMap) {
-        return new DualTreeBidiMap(normalMap, reverseMap, inverseMap);
+    protected DualTreeBidiMap<V, K> createBidiMap(Map<V, K> normalMap, Map<K, 
V> reverseMap, BidiMap<K, V> inverseMap) {
+        return new DualTreeBidiMap<V, K>(normalMap, reverseMap, inverseMap);
     }
 
     //-----------------------------------------------------------------------
-    public Comparator comparator() {
-        return ((SortedMap) maps[0]).comparator();
+    public Comparator<? super K> comparator() {
+        return ((SortedMap<K, V>) normalMap).comparator();
     }
 
-    public Object firstKey() {
-        return ((SortedMap) maps[0]).firstKey();
+    public Comparator<? super V> valueComparator() {
+        return ((SortedMap<V, K>) reverseMap).comparator();
+        
     }
 
-    public Object lastKey() {
-        return ((SortedMap) maps[0]).lastKey();
+    public K firstKey() {
+        return ((SortedMap<K, V>) normalMap).firstKey();
     }
 
-    public Object nextKey(Object key) {
+    public K lastKey() {
+        return ((SortedMap<K, V>) normalMap).lastKey();
+    }
+
+    public K nextKey(K key) {
         if (isEmpty()) {
             return null;
         }
-        if (maps[0] instanceof OrderedMap) {
-            return ((OrderedMap) maps[0]).nextKey(key);
+        if (normalMap instanceof OrderedMap) {
+            return ((OrderedMap<K, ?>) normalMap).nextKey(key);
         }
-        SortedMap sm = (SortedMap) maps[0];
-        Iterator it = sm.tailMap(key).keySet().iterator();
+        SortedMap<K, V> sm = (SortedMap<K, V>) normalMap;
+        Iterator<K> it = sm.tailMap(key).keySet().iterator();
         it.next();
         if (it.hasNext()) {
             return it.next();
@@ -146,15 +159,15 @@
         return null;
     }
 
-    public Object previousKey(Object key) {
+    public K previousKey(K key) {
         if (isEmpty()) {
             return null;
         }
-        if (maps[0] instanceof OrderedMap) {
-            return ((OrderedMap) maps[0]).previousKey(key);
+        if (normalMap instanceof OrderedMap) {
+            return ((OrderedMap<K, V>) normalMap).previousKey(key);
         }
-        SortedMap sm = (SortedMap) maps[0];
-        SortedMap hm = sm.headMap(key);
+        SortedMap<K, V> sm = (SortedMap<K, V>) normalMap;
+        SortedMap<K, V> hm = sm.headMap(key);
         if (hm.isEmpty()) {
             return null;
         }
@@ -167,81 +180,94 @@
      * <p>
      * This implementation copies the elements to an ArrayList in order to
      * provide the forward/backward behaviour.
-     * 
+     *
      * @return a new ordered map iterator
      */
-    public OrderedMapIterator orderedMapIterator() {
-        return new BidiOrderedMapIterator(this);
+    public OrderedMapIterator<K, V> mapIterator() {
+        return new BidiOrderedMapIterator<K, V>(this);
     }
 
-    public SortedBidiMap inverseSortedBidiMap() {
-        return (SortedBidiMap) inverseBidiMap();
+    public SortedBidiMap<V, K> inverseSortedBidiMap() {
+        return (SortedBidiMap<V, K>) inverseBidiMap();
     }
 
-    public OrderedBidiMap inverseOrderedBidiMap() {
-        return (OrderedBidiMap) inverseBidiMap();
+    public OrderedBidiMap<V, K> inverseOrderedBidiMap() {
+        return (OrderedBidiMap<V, K>) inverseBidiMap();
     }
 
     //-----------------------------------------------------------------------
-    public SortedMap headMap(Object toKey) {
-        SortedMap sub = ((SortedMap) maps[0]).headMap(toKey);
-        return new ViewMap(this, sub);
+    public SortedMap<K, V> headMap(K toKey) {
+        SortedMap<K, V> sub = ((SortedMap<K, V>) normalMap).headMap(toKey);
+        return new ViewMap<K, V>(this, sub);
     }
 
-    public SortedMap tailMap(Object fromKey) {
-        SortedMap sub = ((SortedMap) maps[0]).tailMap(fromKey);
-        return new ViewMap(this, sub);
+    public SortedMap<K, V> tailMap(K fromKey) {
+        SortedMap<K, V> sub = ((SortedMap<K, V>) normalMap).tailMap(fromKey);
+        return new ViewMap<K, V>(this, sub);
     }
 
-    public SortedMap subMap(Object fromKey, Object toKey) {
-        SortedMap sub = ((SortedMap) maps[0]).subMap(fromKey, toKey);
-        return new ViewMap(this, sub);
+    public SortedMap<K, V> subMap(K fromKey, K toKey) {
+        SortedMap<K, V> sub = ((SortedMap<K, V>) normalMap).subMap(fromKey, 
toKey);
+        return new ViewMap<K, V>(this, sub);
     }
-    
+
+    /**
+     * {...@inheritdoc}
+     */
+    @Override
+    public SortedBidiMap<V, K> inverseBidiMap() {
+        return (SortedBidiMap<V, K>) super.inverseBidiMap();
+    }
+
     //-----------------------------------------------------------------------
     /**
      * Internal sorted map view.
      */
-    protected static class ViewMap extends AbstractSortedMapDecorator {
+    protected static class ViewMap<K, V> extends AbstractSortedMapDecorator<K, 
V> {
         /** The parent bidi map. */
-        final DualTreeBidiMap bidi;
-        
+        final DualTreeBidiMap<K, V> bidi;
+
         /**
          * Constructor.
          * @param bidi  the parent bidi map
          * @param sm  the subMap sorted map
          */
-        protected ViewMap(DualTreeBidiMap bidi, SortedMap sm) {
+        protected ViewMap(DualTreeBidiMap<K, V> bidi, SortedMap<K, V> sm) {
             // the implementation is not great here...
-            // use the maps[0] as the filtered map, but maps[1] as the full map
+            // use the normalMap as the filtered map, but reverseMap as the 
full map
             // this forces containsValue and clear to be overridden
-            super((SortedMap) bidi.createBidiMap(sm, bidi.maps[1], 
bidi.inverseBidiMap));
-            this.bidi = (DualTreeBidiMap) map;
+            super(new DualTreeBidiMap<K, V>(sm, bidi.reverseMap, 
bidi.inverseBidiMap));
+            this.bidi = (DualTreeBidiMap<K, V>) decorated();
         }
-        
+
         public boolean containsValue(Object value) {
-            // override as default implementation jumps to [1]
-            return bidi.maps[0].containsValue(value);
+            // override as default implementation uses reverseMap
+            return decorated().normalMap.containsValue(value);
         }
-        
+
         public void clear() {
-            // override as default implementation jumps to [1]
-            for (Iterator it = keySet().iterator(); it.hasNext();) {
+            // override as default implementation uses reverseMap
+            for (Iterator<K> it = keySet().iterator(); it.hasNext();) {
                 it.next();
                 it.remove();
             }
         }
-        
-        public SortedMap headMap(Object toKey) {
-            return new ViewMap(bidi, super.headMap(toKey));
+
+        public SortedMap<K, V> headMap(K toKey) {
+            return new ViewMap<K, V>(decorated(), super.headMap(toKey));
+        }
+
+        public SortedMap<K, V> tailMap(K fromKey) {
+            return new ViewMap<K, V>(decorated(), super.tailMap(fromKey));
         }
 
-        public SortedMap tailMap(Object fromKey) {
-            return new ViewMap(bidi, super.tailMap(fromKey));
+        public SortedMap<K, V> subMap(K fromKey, K toKey) {
+            return new ViewMap<K, V>(decorated(), super.subMap(fromKey, 
toKey));
         }
 
-        public SortedMap subMap(Object fromKey, Object toKey) {
-            return new ViewMap(bidi, super.subMap(fromKey, toKey));
+        @Override
+        protected DualTreeBidiMap<K, V> decorated() {
+            return (DualTreeBidiMap<K, V>) super.decorated();
         }
     }
 
@@ -249,99 +275,101 @@
     /**
      * Inner class MapIterator.
      */
-    protected static class BidiOrderedMapIterator implements 
OrderedMapIterator, ResettableIterator {
-        
+    protected static class BidiOrderedMapIterator<K, V> implements 
OrderedMapIterator<K, V>, ResettableIterator<K> {
+
         /** The parent map */
-        protected final AbstractDualBidiMap parent;
+        protected final AbstractDualBidiMap<K, V> parent;
+
         /** The iterator being decorated */
-        protected ListIterator iterator;
+        protected ListIterator<Map.Entry<K, V>> iterator;
+
         /** The last returned entry */
-        private Map.Entry last = null;
-        
+        private Map.Entry<K, V> last = null;
+
         /**
          * Constructor.
          * @param parent  the parent map
          */
-        protected BidiOrderedMapIterator(AbstractDualBidiMap parent) {
+        protected BidiOrderedMapIterator(AbstractDualBidiMap<K, V> parent) {
             super();
             this.parent = parent;
-            iterator = new ArrayList(parent.entrySet()).listIterator();
+            iterator = new ArrayList<Map.Entry<K, 
V>>(parent.entrySet()).listIterator();
         }
-        
+
         public boolean hasNext() {
             return iterator.hasNext();
         }
-        
-        public Object next() {
-            last = (Map.Entry) iterator.next();
+
+        public K next() {
+            last = iterator.next();
             return last.getKey();
         }
-        
+
         public boolean hasPrevious() {
             return iterator.hasPrevious();
         }
-        
-        public Object previous() {
-            last = (Map.Entry) iterator.previous();
+
+        public K previous() {
+            last = iterator.previous();
             return last.getKey();
         }
-        
+
         public void remove() {
             iterator.remove();
             parent.remove(last.getKey());
             last = null;
         }
-        
-        public Object getKey() {
+
+        public K getKey() {
             if (last == null) {
                 throw new IllegalStateException("Iterator getKey() can only be 
called after next() and before remove()");
             }
             return last.getKey();
         }
 
-        public Object getValue() {
+        public V getValue() {
             if (last == null) {
                 throw new IllegalStateException("Iterator getValue() can only 
be called after next() and before remove()");
             }
             return last.getValue();
         }
-        
-        public Object setValue(Object value) {
+
+        public V setValue(V value) {
             if (last == null) {
                 throw new IllegalStateException("Iterator setValue() can only 
be called after next() and before remove()");
             }
-            if (parent.maps[1].containsKey(value) &&
-                parent.maps[1].get(value) != last.getKey()) {
+            if (parent.reverseMap.containsKey(value) &&
+                parent.reverseMap.get(value) != last.getKey()) {
                 throw new IllegalArgumentException("Cannot use setValue() when 
the object being set is already in the map");
             }
             return parent.put(last.getKey(), value);
         }
-        
+
         public void reset() {
-            iterator = new ArrayList(parent.entrySet()).listIterator();
+            iterator = new ArrayList<Map.Entry<K, 
V>>(parent.entrySet()).listIterator();
             last = null;
         }
-        
+
         public String toString() {
             if (last != null) {
                 return "MapIterator[" + getKey() + "=" + getValue() + "]";
-            } else {
-                return "MapIterator[]";
             }
+            return "MapIterator[]";
         }
     }
-    
+
     // Serialization
     //-----------------------------------------------------------------------
     private void writeObject(ObjectOutputStream out) throws IOException {
         out.defaultWriteObject();
-        out.writeObject(maps[0]);
+        out.writeObject(normalMap);
     }
 
+    @SuppressWarnings("unchecked")
     private void readObject(ObjectInputStream in) throws IOException, 
ClassNotFoundException {
         in.defaultReadObject();
-        maps[0] = new TreeMap(comparator);
-        maps[1] = new TreeMap(comparator);
+        normalMap = new TreeMap(comparator);
+        reverseMap = new TreeMap(comparator);
         Map map = (Map) in.readObject();
         putAll(map);
     }


Reply via email to