You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ba...@apache.org on 2009/09/15 07:54:21 UTC

svn commit: r815025 - /commons/proper/collections/trunk/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java

Author: bayard
Date: Tue Sep 15 05:54:21 2009
New Revision: 815025

URL: http://svn.apache.org/viewvc?rev=815025&view=rev
Log:
Merging from -r468106:814127 of collections_jdk5_branch - namely where this code was generified; mostly in r738956.

Also see the following revisions:

    ------------------------------------------------------------------------
    r751871 | mbenson | 2009-03-09 15:13:34 -0700 (Mon, 09 Mar 2009) | 1 line
    
    Add OrderedMap to our SortedMap implementations
    ------------------------------------------------------------------------

Modified:
    commons/proper/collections/trunk/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java

Modified: commons/proper/collections/trunk/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java
URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java?rev=815025&r1=815024&r2=815025&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java (original)
+++ commons/proper/collections/trunk/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java Tue Sep 15 05:54:21 2009
@@ -55,90 +55,103 @@
  * @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 Comparator<? super V> valueComparator() {
+        return ((SortedMap<V, K>) reverseMap).comparator();
+        
     }
 
-    public Object firstKey() {
-        return ((SortedMap) maps[0]).firstKey();
+    public K firstKey() {
+        return ((SortedMap<K, V>) normalMap).firstKey();
     }
 
-    public Object lastKey() {
-        return ((SortedMap) maps[0]).lastKey();
+    public K lastKey() {
+        return ((SortedMap<K, V>) normalMap).lastKey();
     }
 
-    public Object nextKey(Object key) {
+    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,181 +180,204 @@
      * <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 tailMap(Object fromKey) {
-            return new ViewMap(bidi, super.tailMap(fromKey));
+        public SortedMap<K, V> tailMap(K fromKey) {
+            return new ViewMap<K, V>(decorated(), super.tailMap(fromKey));
         }
 
-        public SortedMap subMap(Object fromKey, Object toKey) {
-            return new ViewMap(bidi, super.subMap(fromKey, toKey));
+        public SortedMap<K, V> subMap(K fromKey, K toKey) {
+            return new ViewMap<K, V>(decorated(), super.subMap(fromKey, toKey));
         }
+
+        @Override
+        protected DualTreeBidiMap<K, V> decorated() {
+            return (DualTreeBidiMap<K, V>) super.decorated();
+        }
+
+        public K previousKey(K key) {
+            return decorated().previousKey(key);
+        };
+
+        public K nextKey(K key) {
+            return decorated().nextKey(key);
+        };
     }
 
     //-----------------------------------------------------------------------
     /**
      * 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);
     }