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 @@ * . * */ -package org.apache.commons.collections; +package org.apache.commons.collections.bidimap; import java.util.Collection; import java.util.Iterator; @@ -75,7 +75,7 @@ import org.apache.commons.collections.pairs.AbstractMapEntryDecorator; * 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 @@ * . * */ -package org.apache.commons.collections; +package org.apache.commons.collections.bidimap; import java.util.Map; @@ -73,9 +73,8 @@ import org.apache.commons.collections.iterators.MapIterator; * 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. * - * @see org.apache.commons.collections.DualHashBidiMap * @since Commons Collections 3.0 - * @version $Revision: 1.6 $ $Date: 2003/11/08 18:40:17 $ + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:46 $ * * @author Stephen Colebourne */ diff --git a/src/java/org/apache/commons/collections/DualHashBidiMap.java b/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java similarity index 96% rename from src/java/org/apache/commons/collections/DualHashBidiMap.java rename to src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java index ee417bf24..8ead533a2 100644 --- a/src/java/org/apache/commons/collections/DualHashBidiMap.java +++ b/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.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/DualHashBidiMap.java,v 1.3 2003/10/10 21:06:17 scolebourne Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/bidimap/DualHashBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -55,7 +55,7 @@ * . * */ -package org.apache.commons.collections; +package org.apache.commons.collections.bidimap; import java.io.IOException; import java.io.ObjectInputStream; @@ -68,7 +68,7 @@ import java.util.Map; * Implementation of 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 @@ * . * */ -package org.apache.commons.collections; +package org.apache.commons.collections.bidimap; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; import java.util.Comparator; import java.util.Iterator; +import java.util.ListIterator; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap; +import org.apache.commons.collections.iterators.ListIteratorWrapper; +import org.apache.commons.collections.iterators.OrderedMapIterator; +import org.apache.commons.collections.iterators.ResettableIterator; import org.apache.commons.collections.map.AbstractSortedMapDecorator; +import org.apache.commons.collections.map.OrderedMap; /** * Implementation of 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 + * . + * + */ +package org.apache.commons.collections.bidimap; + +import org.apache.commons.collections.map.OrderedMap; + +/** + * Defines a map that allows bidirectional lookup between key and values + * and retains and provides access to an ordering. + *

+ * 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 @@ * . * */ -package org.apache.commons.collections; +package org.apache.commons.collections.bidimap; import java.util.SortedMap; @@ -67,11 +67,28 @@ import java.util.SortedMap; * a key to be looked up from a value with equal performance. * * @since Commons Collections 3.0 - * @version $Revision: 1.1 $ $Date: 2003/09/21 15:23:04 $ + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:46 $ * * @author Stephen Colebourne */ -public interface SortedBidiMap extends SortedMap, BidiMap { +public interface SortedBidiMap extends OrderedBidiMap, SortedMap { + + /** + * 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 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 @@ * . * */ -package org.apache.commons.collections; +package org.apache.commons.collections.bidimap; import java.util.AbstractSet; import java.util.Collection; @@ -65,7 +65,9 @@ import java.util.Map; import java.util.NoSuchElementException; import java.util.Set; +import org.apache.commons.collections.IteratorUtils; import org.apache.commons.collections.iterators.MapIterator; +import org.apache.commons.collections.iterators.OrderedIterator; import org.apache.commons.collections.iterators.OrderedMapIterator; import org.apache.commons.collections.pairs.UnmodifiableMapEntry; @@ -84,21 +86,17 @@ import org.apache.commons.collections.pairs.UnmodifiableMapEntry; * and redirecting requests to the appropriate TreeMap (e.g., * containsKey would be directed to the TreeMap that maps values to * keys, containsValue would be directed to the TreeMap that maps keys - * to values), there are problems with that implementation, - * particularly when trying to keep the two TreeMaps synchronized with - * each other. And if the data contained in the TreeMaps is large, the - * cost of redundant storage becomes significant. (See also the - * {@link org.apache.commons.collections.DualTreeBidiMap DualTreeBidiMap} and - * {@link org.apache.commons.collections.DualHashBidiMap DualHashBidiMap} - * implementations.) + * to values), there are problems with that implementation. + * If the data contained in the TreeMaps is large, the cost of redundant + * storage becomes significant. The {@link DualTreeBidiMap} and + * {@link DualHashBidiMap} implementations use this approach. *

- * 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: +

    +
  • DualHash - uses two HashMaps to implement BidiMap +
  • DualTree - uses two TreeMaps to implement SortedBidiMap +
  • Tree - red-black tree implementation of OrderedBidiMap + +
+ + diff --git a/src/java/org/apache/commons/collections/map/OrderedMap.java b/src/java/org/apache/commons/collections/map/OrderedMap.java new file mode 100644 index 000000000..011ab4a1f --- /dev/null +++ b/src/java/org/apache/commons/collections/map/OrderedMap.java @@ -0,0 +1,127 @@ +/* + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/map/Attic/OrderedMap.java,v 1.1 2003/11/16 20:35:47 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 + * . + * + */ +package org.apache.commons.collections.map; + +import java.util.Map; + +import org.apache.commons.collections.iterators.OrderedMapIterator; + +/** + * Defines a map that maintains order and allows both forward and backward + * iteration through that order. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:47 $ + * + * @author Stephen Colebourne + */ +public interface OrderedMap extends Map { + + /** + * Obtains an 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 @@ * . * */ -package org.apache.commons.collections; +package org.apache.commons.collections.bidimap; import java.util.Collection; import java.util.HashMap; @@ -63,13 +63,15 @@ import java.util.Iterator; import java.util.Map; import java.util.Set; +import org.apache.commons.collections.AbstractTestMap; +import org.apache.commons.collections.BulkTest; import org.apache.commons.collections.iterators.AbstractTestMapIterator; import org.apache.commons.collections.iterators.MapIterator; /** * Abstract test class for {@link BidiMap} methods and contracts. * - * @version $Revision: 1.8 $ $Date: 2003/11/08 18:46:57 $ + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:46 $ * * @author Matthew Hawthorne * @author Stephen Colebourne diff --git a/src/test/org/apache/commons/collections/TestTreeBidiMap.java b/src/test/org/apache/commons/collections/bidimap/AbstractTestOrderedBidiMap.java similarity index 55% rename from src/test/org/apache/commons/collections/TestTreeBidiMap.java rename to src/test/org/apache/commons/collections/bidimap/AbstractTestOrderedBidiMap.java index f7e96e23d..17dfc706c 100644 --- a/src/test/org/apache/commons/collections/TestTreeBidiMap.java +++ b/src/test/org/apache/commons/collections/bidimap/AbstractTestOrderedBidiMap.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/TestTreeBidiMap.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/test/org/apache/commons/collections/bidimap/AbstractTestOrderedBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -55,109 +55,82 @@ * . * */ -package org.apache.commons.collections; +package org.apache.commons.collections.bidimap; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; -import java.util.Map; import java.util.NoSuchElementException; -import java.util.TreeMap; -import junit.framework.Test; -import junit.textui.TestRunner; +import org.apache.commons.collections.iterators.MapIterator; +import org.apache.commons.collections.iterators.OrderedMapIterator; /** - * JUnit tests. + * Abstract test class for {@link OrderedBidiMap} methods and contracts. * - * @version $Revision: 1.1 $ $Date: 2003/11/08 18:52:51 $ + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:46 $ * + * @author Matthew Hawthorne * @author Stephen Colebourne */ -public class TestTreeBidiMap extends AbstractTestBidiMap { +public abstract class AbstractTestOrderedBidiMap extends AbstractTestBidiMap { - public static void main(String[] args) { - TestRunner.run(suite()); - } - - public static Test suite() { - return BulkTest.makeSuite(TestTreeBidiMap.class); - } - - public TestTreeBidiMap(String testName) { + public AbstractTestOrderedBidiMap(String testName) { super(testName); } - protected BidiMap makeEmptyBidiMap() { - return new TreeBidiMap(); - } - - protected Map makeConfirmedMap() { - return new TreeMap(); + public AbstractTestOrderedBidiMap() { + super(); } - /** - * Override to prevent infinite recursion of tests. - */ - protected String[] ignoredTests() { - return new String[] {"TestTreeBidiMap.bulkTestInverseMap.bulkTestInverseMap"}; - } - - protected boolean isAllowNullKey() { - return false; - } - - protected boolean isAllowNullValue() { - return false; - } - - protected boolean isSetValueSupported() { - return false; - } - + //----------------------------------------------------------------------- public void testFirstKey() { - TreeBidiMap bidi = (TreeBidiMap) makeEmptyMap(); + resetEmpty(); + OrderedBidiMap bidi = (OrderedBidiMap) map; try { bidi.firstKey(); fail(); } catch (NoSuchElementException ex) {} resetFull(); - bidi = (TreeBidiMap) map; + bidi = (OrderedBidiMap) map; Object confirmedFirst = confirmed.keySet().iterator().next(); assertEquals(confirmedFirst, bidi.firstKey()); } public void testLastKey() { - TreeBidiMap bidi = (TreeBidiMap) makeEmptyMap(); + resetEmpty(); + OrderedBidiMap bidi = (OrderedBidiMap) map; try { bidi.lastKey(); fail(); } catch (NoSuchElementException ex) {} resetFull(); - bidi = (TreeBidiMap) map; + bidi = (OrderedBidiMap) map; Object confirmedLast = null; for (Iterator it = confirmed.keySet().iterator(); it.hasNext();) { confirmedLast = it.next(); } assertEquals(confirmedLast, bidi.lastKey()); } - + + //----------------------------------------------------------------------- public void testNextKey() { - TreeBidiMap bidi = (TreeBidiMap) makeEmptyMap(); - try { - bidi.nextKey(null); - fail(); - } catch (NullPointerException ex) {} - try { - bidi.nextKey(new Object()); - fail(); - } catch (ClassCastException ex) {} + resetEmpty(); + OrderedBidiMap bidi = (OrderedBidiMap) map; + assertEquals(null, bidi.nextKey(getOtherKeys()[0])); + if (isAllowNullKey() == false) { + try { + assertEquals(null, bidi.nextKey(null)); // this is allowed too + } catch (NullPointerException ex) {} + } else { + assertEquals(null, bidi.nextKey(null)); + } resetFull(); - bidi = (TreeBidiMap) map; + bidi = (OrderedBidiMap) map; Iterator it = confirmed.keySet().iterator(); Object confirmedLast = it.next(); while (it.hasNext()) { @@ -167,29 +140,30 @@ public class TestTreeBidiMap extends AbstractTestBidiMap { } assertEquals(null, bidi.nextKey(confirmedLast)); - try { - bidi.nextKey(null); - fail(); - } catch (NullPointerException ex) {} - try { - bidi.nextKey(new Object()); - fail(); - } catch (ClassCastException ex) {} + if (isAllowNullKey() == false) { + try { + bidi.nextKey(null); + fail(); + } catch (NullPointerException ex) {} + } else { + assertEquals(null, bidi.nextKey(null)); + } } public void testPreviousKey() { - TreeBidiMap bidi = (TreeBidiMap) makeEmptyMap(); - try { - bidi.previousKey(null); - fail(); - } catch (NullPointerException ex) {} - try { - bidi.previousKey(new Object()); - fail(); - } catch (ClassCastException ex) {} + resetEmpty(); + OrderedBidiMap bidi = (OrderedBidiMap) map; + assertEquals(null, bidi.previousKey(getOtherKeys()[0])); + if (isAllowNullKey() == false) { + try { + assertEquals(null, bidi.previousKey(null)); // this is allowed too + } catch (NullPointerException ex) {} + } else { + assertEquals(null, bidi.previousKey(null)); + } resetFull(); - bidi = (TreeBidiMap) map; + bidi = (OrderedBidiMap) map; List list = new ArrayList(confirmed.keySet()); Collections.reverse(list); Iterator it = list.iterator(); @@ -201,14 +175,45 @@ public class TestTreeBidiMap extends AbstractTestBidiMap { } assertEquals(null, bidi.previousKey(confirmedLast)); - try { - bidi.previousKey(null); - fail(); - } catch (NullPointerException ex) {} - try { - bidi.previousKey(new Object()); - fail(); - } catch (ClassCastException ex) {} + if (isAllowNullKey() == false) { + try { + bidi.previousKey(null); + fail(); + } catch (NullPointerException ex) {} + } else { + assertEquals(null, bidi.previousKey(null)); + } + } + + //----------------------------------------------------------------------- + public void testMapIteratorOrder() { + resetFull(); + OrderedBidiMap bidi = (OrderedBidiMap) map; + List ordered = new ArrayList(map.keySet()); + List ordered2 = new ArrayList(map.keySet()); + assertEquals("KeySet iterator is not consistent", ordered, ordered2); + + int i = 0; + for (MapIterator it = bidi.mapIterator(); it.hasNext(); i++) { + Object key = (Object) it.next(); + assertEquals("Inconsistent order", ordered.get(i), key); + assertEquals("Incorrect value for key", bidi.get(key), it.getValue()); + } + i = 0; + OrderedMapIterator it = bidi.orderedMapIterator(); + for (; it.hasNext(); i++) { + Object key = (Object) it.next(); + assertEquals("Inconsistent order", ordered.get(i), key); + assertEquals("Incorrect value for key", bidi.get(key), it.getValue()); + assertEquals(true, it.hasPrevious()); + } + i--; + for (; it.hasPrevious(); i--) { + Object key = (Object) it.previous(); + assertEquals("Inconsistent order", ordered.get(i), key); + assertEquals("Incorrect value for key", bidi.get(key), it.getValue()); + assertEquals(true, it.hasNext()); + } } } diff --git a/src/test/org/apache/commons/collections/AbstractTestSortedBidiMap.java b/src/test/org/apache/commons/collections/bidimap/AbstractTestSortedBidiMap.java similarity index 97% rename from src/test/org/apache/commons/collections/AbstractTestSortedBidiMap.java rename to src/test/org/apache/commons/collections/bidimap/AbstractTestSortedBidiMap.java index 6146e93a6..93ac3b0a6 100644 --- a/src/test/org/apache/commons/collections/AbstractTestSortedBidiMap.java +++ b/src/test/org/apache/commons/collections/bidimap/AbstractTestSortedBidiMap.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/AbstractTestSortedBidiMap.java,v 1.2 2003/11/01 18:47:18 scolebourne Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/bidimap/AbstractTestSortedBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -55,7 +55,7 @@ * . * */ -package org.apache.commons.collections; +package org.apache.commons.collections.bidimap; import java.util.ArrayList; import java.util.Arrays; @@ -69,17 +69,19 @@ import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; +import org.apache.commons.collections.AbstractTestSortedMap; +import org.apache.commons.collections.BulkTest; import org.apache.commons.collections.pairs.DefaultMapEntry; /** * Abstract test class for {@link BidiMap} methods and contracts. * - * @version $Revision: 1.2 $ $Date: 2003/11/01 18:47:18 $ + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:46 $ * * @author Matthew Hawthorne * @author Stephen Colebourne */ -public abstract class AbstractTestSortedBidiMap extends AbstractTestBidiMap { +public abstract class AbstractTestSortedBidiMap extends AbstractTestOrderedBidiMap { protected List sortedKeys = new ArrayList(); protected List sortedValues = new ArrayList(); @@ -128,21 +130,6 @@ public abstract class AbstractTestSortedBidiMap extends AbstractTestBidiMap { return new TreeMap(); } - //----------------------------------------------------------------------- - public void testFirstKey() { - SortedMap sm = (SortedMap) makeFullMap(); - assertSame(sm.keySet().iterator().next(), sm.firstKey()); - } - - public void testLastKey() { - SortedMap sm = (SortedMap) makeFullMap(); - Object obj = null; - for (Iterator it = sm.keySet().iterator(); it.hasNext();) { - obj = (Object) it.next(); - } - assertSame(obj, sm.lastKey()); - } - //----------------------------------------------------------------------- //----------------------------------------------------------------------- public void testBidiHeadMapContains() { diff --git a/src/test/org/apache/commons/collections/bidimap/TestAll.java b/src/test/org/apache/commons/collections/bidimap/TestAll.java new file mode 100644 index 000000000..0b68cd722 --- /dev/null +++ b/src/test/org/apache/commons/collections/bidimap/TestAll.java @@ -0,0 +1,93 @@ +/* + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/bidimap/TestAll.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $ + * ==================================================================== + * + * The Apache Software License, Version 1.1 + * + * Copyright (c) 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 + * . + * + */ +package org.apache.commons.collections.bidimap; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Entry point for tests. + * + * @since Commons Collections 3.0 + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:46 $ + * + * @author Stephen Colebourne + */ +public class TestAll extends TestCase { + + public TestAll(String testName) { + super(testName); + } + + public static void main(String args[]) { + String[] testCaseName = { TestAll.class.getName() }; + junit.textui.TestRunner.main(testCaseName); + } + + public static Test suite() { + TestSuite suite = new TestSuite(); + + suite.addTest(TestDualHashBidiMap.suite()); + suite.addTest(TestDualTreeBidiMap.suite()); + suite.addTest(TestTreeBidiMap.suite()); + + return suite; + } + +} diff --git a/src/test/org/apache/commons/collections/TestDualHashBidiMap.java b/src/test/org/apache/commons/collections/bidimap/TestDualHashBidiMap.java similarity index 85% rename from src/test/org/apache/commons/collections/TestDualHashBidiMap.java rename to src/test/org/apache/commons/collections/bidimap/TestDualHashBidiMap.java index 0efe020c7..f50a4d28f 100644 --- a/src/test/org/apache/commons/collections/TestDualHashBidiMap.java +++ b/src/test/org/apache/commons/collections/bidimap/TestDualHashBidiMap.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/TestDualHashBidiMap.java,v 1.2 2003/10/10 21:11:39 scolebourne Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/bidimap/TestDualHashBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -55,15 +55,17 @@ * . * */ -package org.apache.commons.collections; +package org.apache.commons.collections.bidimap; import junit.framework.Test; import junit.textui.TestRunner; +import org.apache.commons.collections.BulkTest; + /** * JUnit tests. * - * @version $Revision: 1.2 $ $Date: 2003/10/10 21:11:39 $ + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:46 $ * * @author Matthew Hawthorne * @author Stephen Colebourne @@ -93,4 +95,10 @@ public class TestDualHashBidiMap extends AbstractTestBidiMap { return new String[] {"TestDualHashBidiMap.bulkTestInverseMap.bulkTestInverseMap"}; } +// public void testCreate() throws Exception { +// resetEmpty(); +// writeExternalFormToDisk((Serializable) map, "D:/dev/collections/data/test/DualHashBidiMap.emptyCollection.version3.obj"); +// resetFull(); +// writeExternalFormToDisk((Serializable) map, "D:/dev/collections/data/test/DualHashBidiMap.fullCollection.version3.obj"); +// } } diff --git a/src/test/org/apache/commons/collections/TestDualTreeBidiMap.java b/src/test/org/apache/commons/collections/bidimap/TestDualTreeBidiMap.java similarity index 85% rename from src/test/org/apache/commons/collections/TestDualTreeBidiMap.java rename to src/test/org/apache/commons/collections/bidimap/TestDualTreeBidiMap.java index 48220bdb3..36d2a9a2a 100644 --- a/src/test/org/apache/commons/collections/TestDualTreeBidiMap.java +++ b/src/test/org/apache/commons/collections/bidimap/TestDualTreeBidiMap.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/TestDualTreeBidiMap.java,v 1.1 2003/10/31 01:26:25 scolebourne Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/bidimap/TestDualTreeBidiMap.java,v 1.1 2003/11/16 20:35:46 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -55,15 +55,17 @@ * . * */ -package org.apache.commons.collections; +package org.apache.commons.collections.bidimap; import junit.framework.Test; import junit.textui.TestRunner; +import org.apache.commons.collections.BulkTest; + /** * JUnit tests. * - * @version $Revision: 1.1 $ $Date: 2003/10/31 01:26:25 $ + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:46 $ * * @author Matthew Hawthorne * @author Stephen Colebourne @@ -93,4 +95,10 @@ public class TestDualTreeBidiMap extends AbstractTestSortedBidiMap { return new String[] {"TestDualTreeBidiMap.bulkTestInverseMap.bulkTestInverseMap"}; } +// public void testCreate() throws Exception { +// resetEmpty(); +// writeExternalFormToDisk((Serializable) map, "D:/dev/collections/data/test/DualTreeBidiMap.emptyCollection.version3.obj"); +// resetFull(); +// writeExternalFormToDisk((Serializable) map, "D:/dev/collections/data/test/DualTreeBidiMap.fullCollection.version3.obj"); +// } } diff --git a/src/test/org/apache/commons/collections/bidimap/TestTreeBidiMap.java b/src/test/org/apache/commons/collections/bidimap/TestTreeBidiMap.java new file mode 100644 index 000000000..e537d2cc8 --- /dev/null +++ b/src/test/org/apache/commons/collections/bidimap/TestTreeBidiMap.java @@ -0,0 +1,116 @@ +/* + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/bidimap/TestTreeBidiMap.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 + * . + * + */ +package org.apache.commons.collections.bidimap; + +import java.util.Map; +import java.util.TreeMap; + +import junit.framework.Test; +import junit.textui.TestRunner; + +import org.apache.commons.collections.BulkTest; + +/** + * JUnit tests. + * + * @version $Revision: 1.1 $ $Date: 2003/11/16 20:35:46 $ + * + * @author Stephen Colebourne + */ +public class TestTreeBidiMap extends AbstractTestBidiMap { + + public static void main(String[] args) { + TestRunner.run(suite()); + } + + public static Test suite() { + return BulkTest.makeSuite(TestTreeBidiMap.class); + } + + public TestTreeBidiMap(String testName) { + super(testName); + } + + protected BidiMap makeEmptyBidiMap() { + return new TreeBidiMap(); + } + + protected Map makeConfirmedMap() { + return new TreeMap(); + } + + /** + * Override to prevent infinite recursion of tests. + */ + protected String[] ignoredTests() { + return new String[] {"TestTreeBidiMap.bulkTestInverseMap.bulkTestInverseMap"}; + } + + protected boolean isAllowNullKey() { + return false; + } + + protected boolean isAllowNullValue() { + return false; + } + + protected boolean isSetValueSupported() { + return false; + } + +} diff --git a/src/test/org/apache/commons/collections/iterators/TestUnmodifiableMapIterator.java b/src/test/org/apache/commons/collections/iterators/TestUnmodifiableMapIterator.java index 041317d75..e4ea8f28d 100644 --- a/src/test/org/apache/commons/collections/iterators/TestUnmodifiableMapIterator.java +++ b/src/test/org/apache/commons/collections/iterators/TestUnmodifiableMapIterator.java @@ -1,5 +1,5 @@ /* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/iterators/TestUnmodifiableMapIterator.java,v 1.2 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/iterators/TestUnmodifiableMapIterator.java,v 1.3 2003/11/16 20:35:47 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -63,14 +63,14 @@ import java.util.Map; import junit.framework.Test; import junit.framework.TestSuite; -import org.apache.commons.collections.BidiMap; -import org.apache.commons.collections.DualHashBidiMap; import org.apache.commons.collections.Unmodifiable; +import org.apache.commons.collections.bidimap.BidiMap; +import org.apache.commons.collections.bidimap.DualHashBidiMap; /** * Tests the UnmodifiableMapIterator. * - * @version $Revision: 1.2 $ $Date: 2003/11/08 18:46:57 $ + * @version $Revision: 1.3 $ $Date: 2003/11/16 20:35:47 $ * * @author Stephen Colebourne */