diff --git a/data/test/DualHashBidiMap.emptyCollection.version3.obj b/data/test/DualHashBidiMap.emptyCollection.version3.obj
index 942ac301b..c8c431895 100644
Binary files a/data/test/DualHashBidiMap.emptyCollection.version3.obj and b/data/test/DualHashBidiMap.emptyCollection.version3.obj differ
diff --git a/data/test/DualHashBidiMap.fullCollection.version3.obj b/data/test/DualHashBidiMap.fullCollection.version3.obj
index 7b8f397e4..a5448baad 100644
Binary files a/data/test/DualHashBidiMap.fullCollection.version3.obj and b/data/test/DualHashBidiMap.fullCollection.version3.obj differ
diff --git a/data/test/DualTreeBidiMap.emptyCollection.version3.obj b/data/test/DualTreeBidiMap.emptyCollection.version3.obj
new file mode 100644
index 000000000..e7875f3fd
Binary files /dev/null and b/data/test/DualTreeBidiMap.emptyCollection.version3.obj differ
diff --git a/data/test/DualTreeBidiMap.fullCollection.version3.obj b/data/test/DualTreeBidiMap.fullCollection.version3.obj
new file mode 100644
index 000000000..ff7ea0940
Binary files /dev/null and b/data/test/DualTreeBidiMap.fullCollection.version3.obj differ
diff --git a/src/java/org/apache/commons/collections/AbstractDualBidiMap.java b/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java
similarity index 98%
rename from src/java/org/apache/commons/collections/AbstractDualBidiMap.java
rename to src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java
index c3d753e31..321911b01 100644
--- a/src/java/org/apache/commons/collections/AbstractDualBidiMap.java
+++ b/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/Attic/AbstractDualBidiMap.java,v 1.11 2003/11/16 00:05:44 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/bidimap/AbstractDualBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -55,7 +55,7 @@
* createMap
method.
*
* @since Commons Collections 3.0
- * @version $Id: AbstractDualBidiMap.java,v 1.11 2003/11/16 00:05:44 scolebourne Exp $
+ * @version $Id: AbstractDualBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $
*
* @author Matthew Hawthorne
* @author Stephen Colebourne
@@ -566,7 +566,7 @@ public abstract class AbstractDualBidiMap implements BidiMap {
}
public Object next() {
- last = new MapEntry((Map.Entry) iterator.next(), map);
+ last = (Map.Entry) iterator.next();
canRemove = true;
return last.getKey();
}
diff --git a/src/java/org/apache/commons/collections/BidiMap.java b/src/java/org/apache/commons/collections/bidimap/BidiMap.java
similarity index 97%
rename from src/java/org/apache/commons/collections/BidiMap.java
rename to src/java/org/apache/commons/collections/bidimap/BidiMap.java
index 96316084a..426fc592a 100644
--- a/src/java/org/apache/commons/collections/BidiMap.java
+++ b/src/java/org/apache/commons/collections/bidimap/BidiMap.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/BidiMap.java,v 1.6 2003/11/08 18:40:17 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/bidimap/Attic/BidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -55,7 +55,7 @@
* BidiMap
that uses two HashMap
instances.
*
* @since Commons Collections 3.0
- * @version $Id: DualHashBidiMap.java,v 1.3 2003/10/10 21:06:17 scolebourne Exp $
+ * @version $Id: DualHashBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $
*
* @author Matthew Hawthorne
* @author Stephen Colebourne
diff --git a/src/java/org/apache/commons/collections/DualTreeBidiMap.java b/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java
similarity index 53%
rename from src/java/org/apache/commons/collections/DualTreeBidiMap.java
rename to src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java
index 451f46183..08e1df0be 100644
--- a/src/java/org/apache/commons/collections/DualTreeBidiMap.java
+++ b/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java
@@ -1,10 +1,10 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/Attic/DualTreeBidiMap.java,v 1.3 2003/11/16 00:05:44 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/bidimap/DualTreeBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
- * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,32 +55,54 @@
* BidiMap
that uses two TreeMap
instances.
+ *
+ * The setValue() method on iterators will succeed only if the new value being set is + * not already in the bidimap. + *
+ * When considering whether to use this class, the {@link TreeBidiMap} class should
+ * also be considered. It implements the interface using a dedicated design, and does
+ * not store each object twice, which can save on memory use.
*
* @since Commons Collections 3.0
- * @version $Id: DualTreeBidiMap.java,v 1.3 2003/11/16 00:05:44 scolebourne Exp $
+ * @version $Id: DualTreeBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $
*
* @author Matthew Hawthorne
* @author Stephen Colebourne
*/
-public class DualTreeBidiMap extends AbstractDualBidiMap implements SortedBidiMap {
+public class DualTreeBidiMap extends AbstractDualBidiMap implements SortedBidiMap, Serializable {
+ /** Ensure serialization compatability */
+ private static final long serialVersionUID = 721969328361809L;
+ /** The comparator to use */
+ protected final Comparator comparator;
+
/**
* Creates an empty DualTreeBidiMap
*/
public DualTreeBidiMap() {
super();
+ this.comparator = null;
}
/**
@@ -92,6 +114,17 @@ public class DualTreeBidiMap extends AbstractDualBidiMap implements SortedBidiMa
public DualTreeBidiMap(Map map) {
super();
putAll(map);
+ this.comparator = null;
+ }
+
+ /**
+ * Constructs a DualTreeBidiMap
using the specified Comparator.
+ *
+ * @param map the map whose mappings are to be placed in this map
+ */
+ public DualTreeBidiMap(Comparator comparator) {
+ super();
+ this.comparator = comparator;
}
/**
@@ -103,6 +136,7 @@ public class DualTreeBidiMap extends AbstractDualBidiMap implements SortedBidiMa
*/
protected DualTreeBidiMap(Map normalMap, Map reverseMap, BidiMap inverseBidiMap) {
super(normalMap, reverseMap, inverseBidiMap);
+ this.comparator = ((SortedMap) normalMap).comparator();
}
/**
@@ -111,7 +145,7 @@ public class DualTreeBidiMap extends AbstractDualBidiMap implements SortedBidiMa
* @return the map to be used for internal storage
*/
protected Map createMap() {
- return new TreeMap();
+ return new TreeMap(comparator);
}
/**
@@ -126,13 +160,6 @@ public class DualTreeBidiMap extends AbstractDualBidiMap implements SortedBidiMa
return new DualTreeBidiMap(normalMap, reverseMap, inverseMap);
}
- // SortedBidiMap
- //-----------------------------------------------------------------------
- public SortedBidiMap inverseSortedBidiMap() {
- return (SortedBidiMap) inverseBidiMap();
- }
-
- // SortedMap
//-----------------------------------------------------------------------
public Comparator comparator() {
return ((SortedMap) maps[0]).comparator();
@@ -146,6 +173,56 @@ public class DualTreeBidiMap extends AbstractDualBidiMap implements SortedBidiMa
return ((SortedMap) maps[0]).lastKey();
}
+ public Object nextKey(Object key) {
+ if (isEmpty()) {
+ return null;
+ }
+ if (maps[0] instanceof OrderedMap) {
+ return ((OrderedMap) maps[0]).nextKey(key);
+ }
+ SortedMap sm = (SortedMap) maps[0];
+ Iterator it = sm.tailMap(key).keySet().iterator();
+ it.next();
+ if (it.hasNext()) {
+ return it.next();
+ }
+ return null;
+ }
+
+ public Object previousKey(Object key) {
+ if (isEmpty()) {
+ return null;
+ }
+ if (maps[0] instanceof OrderedMap) {
+ return ((OrderedMap) maps[0]).previousKey(key);
+ }
+ SortedMap sm = (SortedMap) maps[0];
+ SortedMap hm = sm.headMap(key);
+ if (hm.isEmpty()) {
+ return null;
+ }
+ return hm.lastKey();
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Obtains an ordered map iterator.
+ *
+ * This implementation copies the elements to an ArrayList in order to
+ * provide the forward/backward behaviour.
+ */
+ public OrderedMapIterator orderedMapIterator() {
+ return new BidiOrderedMapIterator(this);
+ }
+
+ public SortedBidiMap inverseSortedBidiMap() {
+ return (SortedBidiMap) inverseBidiMap();
+ }
+
+ public OrderedBidiMap inverseOrderedBidiMap() {
+ return (OrderedBidiMap) inverseBidiMap();
+ }
+
//-----------------------------------------------------------------------
public SortedMap headMap(Object toKey) {
SortedMap sub = ((SortedMap) maps[0]).headMap(toKey);
@@ -162,6 +239,7 @@ public class DualTreeBidiMap extends AbstractDualBidiMap implements SortedBidiMa
return new ViewMap(this, sub);
}
+ //-----------------------------------------------------------------------
protected static class ViewMap extends AbstractSortedMapDecorator {
final DualTreeBidiMap bidi;
@@ -199,4 +277,95 @@ public class DualTreeBidiMap extends AbstractDualBidiMap implements SortedBidiMa
}
}
+ //-----------------------------------------------------------------------
+ /**
+ * Inner class MapIterator.
+ */
+ protected static class BidiOrderedMapIterator implements OrderedMapIterator, ResettableIterator {
+
+ protected final AbstractDualBidiMap map;
+ protected ListIterator iterator;
+ private Map.Entry last = null;
+
+ protected BidiOrderedMapIterator(AbstractDualBidiMap map) {
+ super();
+ this.map = map;
+ iterator = new ListIteratorWrapper(map.entrySet().iterator());
+ }
+
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ public Object next() {
+ last = (Map.Entry) iterator.next();
+ return last.getKey();
+ }
+
+ public boolean hasPrevious() {
+ return iterator.hasPrevious();
+ }
+
+ public Object previous() {
+ last = (Map.Entry) iterator.previous();
+ return last.getKey();
+ }
+
+ public void remove() {
+ iterator.remove();
+ map.remove(last.getKey());
+ }
+
+ public Object getKey() {
+ if (last == null) {
+ throw new IllegalStateException("Iterator getKey() can only be called after next() and before remove()");
+ }
+ return last.getKey();
+ }
+
+ public Object 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) {
+ if (last == null) {
+ throw new IllegalStateException("Iterator setValue() can only be called after next() and before remove()");
+ }
+ if (map.maps[1].containsKey(value) &&
+ map.maps[1].get(value) != last.getKey()) {
+ throw new IllegalArgumentException("Cannot use setValue() when the object being set is already in the map");
+ }
+ return map.put(last.getKey(), value);
+ }
+
+ public void reset() {
+ iterator = new ListIteratorWrapper(map.entrySet().iterator());
+ last = null;
+ }
+
+ public String toString() {
+ if (last == null) {
+ return "MapIterator[" + getKey() + "=" + getValue() + "]";
+ } else {
+ return "MapIterator[]";
+ }
+ }
+ }
+
+ // Serialization
+ //-----------------------------------------------------------------------
+ private void writeObject(ObjectOutputStream out) throws IOException {
+ out.defaultWriteObject();
+ out.writeObject(maps[0]);
+ }
+
+ private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
+ in.defaultReadObject();
+ Map map = (Map) in.readObject();
+ putAll(map);
+ }
+
}
diff --git a/src/java/org/apache/commons/collections/bidimap/OrderedBidiMap.java b/src/java/org/apache/commons/collections/bidimap/OrderedBidiMap.java
new file mode 100644
index 000000000..b84475a15
--- /dev/null
+++ b/src/java/org/apache/commons/collections/bidimap/OrderedBidiMap.java
@@ -0,0 +1,107 @@
+/*
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/bidimap/Attic/OrderedBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ * any, must include the following acknowledgement:
+ * "This product includes software developed by the
+ * Apache Software Foundation (http://www.apache.org/)."
+ * Alternately, this acknowledgement may appear in the software itself,
+ * if and wherever such third-party acknowledgements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Commons", and "Apache Software
+ * Foundation" must not be used to endorse or promote products derived
+ * from this software without prior written permission. For written
+ * permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ * nor may "Apache" appear in their names without prior written
+ * permission of the Apache Software Foundation.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ *
+ * Implementations should allow a value to be looked up from a key and + * a key to be looked up from a value with equal performance. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:46 $ + * + * @author Stephen Colebourne + */ +public interface OrderedBidiMap extends BidiMap, OrderedMap { + + /** + * Gets a view of this map where the keys and values are reversed. + *
+ * Changes to one map will be visible in the other and vice versa. + * This enables both directions of the map to be accessed equally. + *
+ * Implementations should seek to avoid creating a new object every time this
+ * method is called. See AbstractMap.values()
etc. Calling this
+ * method on the inverse map should return the original.
+ *
+ * Implementations must return an OrderedBidiMap
instance,
+ * usually by forwarding to inverseOrderedBidiMap()
.
+ *
+ * @return an inverted bidirectional map
+ */
+ public BidiMap inverseBidiMap();
+
+ /**
+ * Gets a view of this map where the keys and values are reversed.
+ *
+ * Changes to one map will be visible in the other and vice versa. + * This enables both directions of the map to be accessed equally. + *
+ * Implementations should seek to avoid creating a new object every time this
+ * method is called. See AbstractMap.values()
etc. Calling this
+ * method on the inverse map should return the original.
+ *
+ * @return an inverted bidirectional map
+ */
+ public OrderedBidiMap inverseOrderedBidiMap();
+
+}
diff --git a/src/java/org/apache/commons/collections/SortedBidiMap.java b/src/java/org/apache/commons/collections/bidimap/SortedBidiMap.java
similarity index 77%
rename from src/java/org/apache/commons/collections/SortedBidiMap.java
rename to src/java/org/apache/commons/collections/bidimap/SortedBidiMap.java
index fff1ec731..4859dc9a1 100644
--- a/src/java/org/apache/commons/collections/SortedBidiMap.java
+++ b/src/java/org/apache/commons/collections/bidimap/SortedBidiMap.java
@@ -1,5 +1,5 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/SortedBidiMap.java,v 1.1 2003/09/21 15:23:04 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/bidimap/Attic/SortedBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
@@ -55,7 +55,7 @@
*
+ * Changes to one map will be visible in the other and vice versa. + * This enables both directions of the map to be accessed equally. + *
+ * Implementations should seek to avoid creating a new object every time this
+ * method is called. See AbstractMap.values()
etc. Calling this
+ * method on the inverse map should return the original.
+ *
+ * Implementations must return a SortedBidiMap
instance,
+ * usually by forwarding to inverseSortedBidiMap()
.
+ *
+ * @return an inverted bidirectional map
+ */
+ public BidiMap inverseBidiMap();
/**
* Gets a view of this map where the keys and values are reversed.
@@ -82,6 +99,9 @@ public interface SortedBidiMap extends SortedMap, BidiMap {
* Implementations should seek to avoid creating a new object every time this
* method is called. See AbstractMap.values()
etc. Calling this
* method on the inverse map should return the original.
+ *
+ * The inverse map returned by inverseBidiMap()
should be the
+ * same object as returned by this method.
*
* @return an inverted bidirectional map
*/
diff --git a/src/java/org/apache/commons/collections/TreeBidiMap.java b/src/java/org/apache/commons/collections/bidimap/TreeBidiMap.java
similarity index 95%
rename from src/java/org/apache/commons/collections/TreeBidiMap.java
rename to src/java/org/apache/commons/collections/bidimap/TreeBidiMap.java
index bacc96a4a..57724513b 100644
--- a/src/java/org/apache/commons/collections/TreeBidiMap.java
+++ b/src/java/org/apache/commons/collections/bidimap/TreeBidiMap.java
@@ -1,10 +1,10 @@
/*
- * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/Attic/TreeBidiMap.java,v 1.1 2003/11/08 18:52:51 scolebourne Exp $
+ * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/bidimap/TreeBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $
* ====================================================================
*
* The Apache Software License, Version 1.1
*
- * Copyright (c) 2002-2003 The Apache Software Foundation. All rights
+ * Copyright (c) 2001-2003 The Apache Software Foundation. All rights
* reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -55,7 +55,7 @@
*
- * This solution keeps the data properly synchronized and minimizes - * the data storage. The red-black algorithm is based on TreeMap's, - * but has been modified to simultaneously map a tree node by key and - * by value. This doubles the cost of put operations (but so does - * using two TreeMaps), and nearly doubles the cost of remove - * operations (there is a savings in that the lookup of the node to be - * removed only has to be performed once). And since only one node + * This solution keeps minimizes the data storage by holding data only once. + * The red-black algorithm is based on java util TreeMap, but has been modified + * to simultaneously map a tree node by key and by value. This doubles the + * cost of put operations (but so does using two TreeMaps), and nearly doubles + * the cost of remove operations (there is a savings in that the lookup of the + * node to be removed only has to be performed once). And since only one node * contains the key and value, storage is significantly less than that * required by two TreeMaps. *
@@ -106,16 +104,13 @@ import org.apache.commons.collections.pairs.UnmodifiableMapEntry; * not allow setValue() and will throw an * UnsupportedOperationException on attempts to call that method. * - * @see BidiMap - * @see DualTreeBidiMap - * @see DualHashBidiMap - * @since Commons Collections 2.0 (previously DoubleOrderedMap) - * @version $Revision: 1.1 $ $Date: 2003/11/08 18:52:51 $ + * @since Commons Collections 3.0 (previously DoubleOrderedMap v2.0) + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:46 $ * * @author Marc Johnson * @author Stephen Colebourne */ -public class TreeBidiMap implements BidiMap { +public class TreeBidiMap implements OrderedBidiMap { private static final int KEY = 0; private static final int VALUE = 1; @@ -429,17 +424,41 @@ public class TreeBidiMap implements BidiMap { */ public MapIterator mapIterator() { if (isEmpty()) { - return IteratorUtils.EMPTY_MAP_ITERATOR; + return IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR; } return new ViewMapIterator(this, KEY); } + /** + * Gets an ordered iterator over the map entries. + *
+ * This iterator allows both forward and reverse iteration over the entries. + * + * @return an iterator + */ + public OrderedMapIterator orderedMapIterator() { + if (isEmpty()) { + return IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR; + } + return new ViewMapIterator(this, KEY); + } + + //----------------------------------------------------------------------- + /** + * Gets the inverse map for comparison. + * + * @return the inverse map + */ + public BidiMap inverseBidiMap() { + return inverseOrderedBidiMap(); + } + /** * Gets the inverse map for comparison. * * @return the inverse map */ - public BidiMap inverseBidiMap() { + public OrderedBidiMap inverseOrderedBidiMap() { if (inverse == null) { inverse = new Inverse(this); } @@ -1508,7 +1527,7 @@ public class TreeBidiMap implements BidiMap { /** * An iterator over the map. */ - static class ViewIterator implements Iterator { + static class ViewIterator implements OrderedIterator { protected final TreeBidiMap main; protected final int orderType; @@ -1913,7 +1932,7 @@ public class TreeBidiMap implements BidiMap { /** * A node used to store the data. */ - static class Inverse implements BidiMap { + static class Inverse implements OrderedBidiMap { private final TreeBidiMap main; private Set keySet; @@ -1949,6 +1968,32 @@ public class TreeBidiMap implements BidiMap { return main.containsKey(value); } + public Object firstKey() { + if (main.nodeCount == 0) { + throw new NoSuchElementException("Map is empty"); + } + return main.leastNode(main.rootNode[VALUE], VALUE).getValue(); + } + + public Object lastKey() { + if (main.nodeCount == 0) { + throw new NoSuchElementException("Map is empty"); + } + return main.greatestNode(main.rootNode[VALUE], VALUE).getValue(); + } + + public Object nextKey(Object key) { + checkKey(key); + Node node = main.nextGreater(main.lookup((Comparable) key, VALUE), VALUE); + return (node == null ? null : node.getValue()); + } + + public Object previousKey(Object key) { + checkKey(key); + Node node = main.nextSmaller(main.lookup((Comparable) key, VALUE), VALUE); + return (node == null ? null : node.getValue()); + } + public Object put(final Object key, final Object value) { return main.doPut((Comparable) value, (Comparable) key, VALUE); } @@ -1996,7 +2041,14 @@ public class TreeBidiMap implements BidiMap { public MapIterator mapIterator() { if (isEmpty()) { - return IteratorUtils.EMPTY_MAP_ITERATOR; + return IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR; + } + return new ViewMapIterator(main, VALUE); + } + + public OrderedMapIterator orderedMapIterator() { + if (isEmpty()) { + return IteratorUtils.EMPTY_ORDERED_MAP_ITERATOR; } return new ViewMapIterator(main, VALUE); } @@ -2005,6 +2057,10 @@ public class TreeBidiMap implements BidiMap { return main; } + public OrderedBidiMap inverseOrderedBidiMap() { + return main; + } + public boolean equals(Object obj) { return main.doEquals(obj, VALUE); } diff --git a/src/java/org/apache/commons/collections/bidimap/package.html b/src/java/org/apache/commons/collections/bidimap/package.html new file mode 100644 index 000000000..bdb978d43 --- /dev/null +++ b/src/java/org/apache/commons/collections/bidimap/package.html @@ -0,0 +1,25 @@ +
++This package contains implementations of the BidiMap, OrderedBidiMap and SortedBidiMap interfaces. +
+The implementations are in the form of direct implementations and decorators. +A decorator wraps another implementation of the interface to add some +specific additional functionality. +
+The following implementations are provided in the package: +
OrderedMapIterator
over the map.
+ * + * A ordered map iterator is an efficient way of iterating over maps + * in both directions. + *
+ * BidiMap map = new TreeBidiMap(); + * MapIterator it = map.mapIterator(); + * while (it.hasNext()) { + * Object key = it.next(); + * Object value = it.getValue(); + * it.setValue("newValue"); + * Object previousKey = it.previous(); + * } + *+ * + * @return a map iterator + */ + OrderedMapIterator orderedMapIterator(); + + /** + * Gets the first key currently in this map. + * + * @return the first key currently in this map + * @throws NoSuchElementException if this map is empty + */ + public Object firstKey(); + + /** + * Gets the last key currently in this map. + * + * @return the last key currently in this map + * @throws NoSuchElementException if this map is empty + */ + public Object lastKey(); + + /** + * Gets the next key after the one specified. + * + * @param key the key to search for next from + * @return the next key, null if no match or at end + */ + public Object nextKey(Object key); + + /** + * Gets the previous key before the one specified. + * + * @param key the key to search for previous from + * @return the previous key, null if no match or at start + */ + public Object previousKey(Object key); + +} diff --git a/src/test/org/apache/commons/collections/TestAll.java b/src/test/org/apache/commons/collections/TestAll.java index 5db5edaec..a323e5920 100644 --- a/src/test/org/apache/commons/collections/TestAll.java +++ b/src/test/org/apache/commons/collections/TestAll.java @@ -1,5 +1,5 @@ /* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/TestAll.java,v 1.53 2003/11/08 18:52:51 scolebourne Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/TestAll.java,v 1.54 2003/11/16 20:35:46 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -64,7 +64,7 @@ import junit.framework.TestSuite; /** * Entry point for all Collections package tests. * - * @version $Revision: 1.53 $ $Date: 2003/11/08 18:52:51 $ + * @version $Revision: 1.54 $ $Date: 2003/11/16 20:35:46 $ * * @author Rodney Waldhoff * @author Stephen Colebourne @@ -96,8 +96,6 @@ public class TestAll extends TestCase { suite.addTest(TestCommonsLinkedList.suite()); suite.addTest(TestCursorableLinkedList.suite()); suite.addTest(TestDoubleOrderedMap.suite()); - suite.addTest(TestDualHashBidiMap.suite()); - suite.addTest(TestDualTreeBidiMap.suite()); suite.addTest(TestExtendedProperties.suite()); suite.addTest(TestFastArrayList.suite()); suite.addTest(TestFastArrayList1.suite()); @@ -115,7 +113,6 @@ public class TestAll extends TestCase { suite.addTest(TestSequencedHashMap.suite()); suite.addTest(TestStaticBucketMap.suite()); suite.addTest(TestTreeBag.suite()); - suite.addTest(TestTreeBidiMap.suite()); suite.addTest(TestUnboundedFifoBuffer.suite()); suite.addTest(TestEnumerationUtils.suite()); return suite; diff --git a/src/test/org/apache/commons/collections/TestAllPackages.java b/src/test/org/apache/commons/collections/TestAllPackages.java index 741fccb8c..57067e435 100644 --- a/src/test/org/apache/commons/collections/TestAllPackages.java +++ b/src/test/org/apache/commons/collections/TestAllPackages.java @@ -1,5 +1,5 @@ /* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/TestAllPackages.java,v 1.6 2003/11/16 00:05:47 scolebourne Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/TestAllPackages.java,v 1.7 2003/11/16 20:35:46 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -64,7 +64,7 @@ import junit.framework.TestSuite; /** * Entry point for all Collections project tests. * - * @version $Revision: 1.6 $ $Date: 2003/11/16 00:05:47 $ + * @version $Revision: 1.7 $ $Date: 2003/11/16 20:35:46 $ * * @author Stephen Colebourne */ @@ -77,6 +77,7 @@ public class TestAllPackages extends TestCase { TestSuite suite = new TestSuite(); suite.addTest(org.apache.commons.collections.TestAll.suite()); suite.addTest(org.apache.commons.collections.bag.TestAll.suite()); + suite.addTest(org.apache.commons.collections.bidimap.TestAll.suite()); suite.addTest(org.apache.commons.collections.buffer.TestAll.suite()); suite.addTest(org.apache.commons.collections.comparators.TestAll.suite()); suite.addTest(org.apache.commons.collections.collection.TestAll.suite()); diff --git a/src/test/org/apache/commons/collections/AbstractTestBidiMap.java b/src/test/org/apache/commons/collections/bidimap/AbstractTestBidiMap.java similarity index 98% rename from src/test/org/apache/commons/collections/AbstractTestBidiMap.java rename to src/test/org/apache/commons/collections/bidimap/AbstractTestBidiMap.java index 320931f41..51f918668 100644 --- a/src/test/org/apache/commons/collections/AbstractTestBidiMap.java +++ b/src/test/org/apache/commons/collections/bidimap/AbstractTestBidiMap.java @@ -1,5 +1,5 @@ /* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/Attic/AbstractTestBidiMap.java,v 1.8 2003/11/08 18:46:57 scolebourne Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/bidimap/AbstractTestBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -55,7 +55,7 @@ *