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);
}