diff --git a/src/java/org/apache/commons/collections/SequencedHashMap.java b/src/java/org/apache/commons/collections/SequencedHashMap.java index 6950045d9..dcf6d364d 100644 --- a/src/java/org/apache/commons/collections/SequencedHashMap.java +++ b/src/java/org/apache/commons/collections/SequencedHashMap.java @@ -1,5 +1,5 @@ /* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/SequencedHashMap.java,v 1.19 2003/08/31 17:26:44 scolebourne Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/SequencedHashMap.java,v 1.20 2003/09/09 22:28:35 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -75,33 +75,34 @@ import java.util.NoSuchElementException; import java.util.Set; /** - * A map of objects whose mapping entries are sequenced based on the order in - * which they were added. This data structure has fast O(1) search - * time, deletion time, and insertion time. - * - *

Although this map is sequenced, it cannot implement {@link - * java.util.List} because of incompatible interface definitions. The remove - * methods in List and Map have different return values (see: {@link - * java.util.List#remove(Object)} and {@link java.util.Map#remove(Object)}). - * - *

This class is not thread safe. When a thread safe implementation is - * required, use {@link Collections#synchronizedMap(Map)} as it is documented, - * or use explicit synchronization controls. + * A map of objects whose mapping entries are sequenced based on the order in + * which they were added. This data structure has fast O(1) search + * time, deletion time, and insertion time. + *

+ * Although this map is sequenced, it cannot implement + * {@link java.util.List} because of incompatible interface definitions. + * The remove methods in List and Map have different return values + * (see: {@link java.util.List#remove(Object)} and {@link java.util.Map#remove(Object)}). + *

+ * This class is not thread safe. When a thread safe implementation is + * required, use {@link Collections#synchronizedMap(Map)} as it is documented, + * or use explicit synchronization controls. * + * @see org.apache.commons.collections.decorators.OrderedSet * @since Commons Collections 2.0 - * @version $Revision: 1.19 $ $Date: 2003/08/31 17:26:44 $ + * @version $Revision: 1.20 $ $Date: 2003/09/09 22:28:35 $ * - * @author Michael A. Smith - * @author Daniel Rall - * @author Henning P. Schmiedehausen + * @author Michael A. Smith + * @author Daniel Rall + * @author Henning P. Schmiedehausen * @author Stephen Colebourne */ public class SequencedHashMap implements Map, Cloneable, Externalizable { /** - * {@link java.util.Map.Entry} that doubles as a node in the linked list - * of sequenced mappings. - **/ + * {@link java.util.Map.Entry} that doubles as a node in the linked list + * of sequenced mappings. + */ private static class Entry implements Map.Entry { // Note: This class cannot easily be made clonable. While the actual // implementation of a clone would be simple, defining the semantics is @@ -172,7 +173,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * Construct an empty sentinel used to hold the head (sentinel.next) and the * tail (sentinel.prev) of the list. The sentinel has a null * key and value. - **/ + */ private static final Entry createSentinel() { Entry s = new Entry(null, null); s.prev = s; @@ -182,12 +183,12 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { /** * Sentinel used to hold the head and tail of the list of entries. - **/ + */ private Entry sentinel; /** * Map of keys to entries - **/ + */ private HashMap entries; /** @@ -195,13 +196,13 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * excluding modifications made through a collection view's iterator * (e.g. entrySet().iterator().remove()). This is used to create a * fail-fast behavior with the iterators. - **/ + */ private transient long modCount = 0; /** * Construct a new sequenced hash map with default initial size and load * factor. - **/ + */ public SequencedHashMap() { sentinel = createSentinel(); entries = new HashMap(); @@ -214,7 +215,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * @param initialSize the initial size for the hash table * * @see HashMap#HashMap(int) - **/ + */ public SequencedHashMap(int initialSize) { sentinel = createSentinel(); entries = new HashMap(initialSize); @@ -229,7 +230,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * @param loadFactor the load factor for the hash table. * * @see HashMap#HashMap(int,float) - **/ + */ public SequencedHashMap(int initialSize, float loadFactor) { sentinel = createSentinel(); entries = new HashMap(initialSize, loadFactor); @@ -239,7 +240,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * Construct a new sequenced hash map and add all the elements in the * specified map. The order in which the mappings in the specified map are * added is defined by {@link #putAll(Map)}. - **/ + */ public SequencedHashMap(Map m) { this(); putAll(m); @@ -248,7 +249,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { /** * Removes an internal entry from the linked list. This does not remove * it from the underlying map. - **/ + */ private void removeEntry(Entry entry) { entry.next.prev = entry.prev; entry.prev.next = entry.next; @@ -257,7 +258,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { /** * Inserts a new internal entry to the tail of the linked list. This does * not add the entry to the underlying map. - **/ + */ private void insertEntry(Entry entry) { entry.next = sentinel; entry.prev = sentinel.prev; @@ -339,7 +340,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * * @return The first entry in the sequence, or null if the * map is empty. - **/ + */ public Map.Entry getFirst() { // sentinel.next points to the "first" element of the sequence -- the head // of the list, which is exactly the entry we need to return. We must test @@ -356,7 +357,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * * @return The first key in the sequence, or null if the * map is empty. - **/ + */ public Object getFirstKey() { // sentinel.next points to the "first" element of the sequence -- the head // of the list -- and the requisite key is returned from it. An empty list @@ -376,7 +377,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * * @return The first value in the sequence, or null if the * map is empty. - **/ + */ public Object getFirstValue() { // sentinel.next points to the "first" element of the sequence -- the head // of the list -- and the requisite value is returned from it. An empty @@ -406,7 +407,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * * @return The last entry in the sequence, or null if the map * is empty. - **/ + */ public Map.Entry getLast() { // sentinel.prev points to the "last" element of the sequence -- the tail // of the list, which is exactly the entry we need to return. We must test @@ -423,7 +424,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * * @return The last key in the sequence, or null if the map is * empty. - **/ + */ public Object getLastKey() { // sentinel.prev points to the "last" element of the sequence -- the tail // of the list -- and the requisite key is returned from it. An empty list @@ -443,7 +444,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * * @return The last value in the sequence, or null if the map * is empty. - **/ + */ public Object getLastValue() { // sentinel.prev points to the "last" element of the sequence -- the tail // of the list -- and the requisite value is returned from it. An empty @@ -502,7 +503,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { /** * Fully remove an entry from the map, returning the old entry or null if * there was no such entry with the specified key. - **/ + */ private Entry removeImpl(Object key) { Entry e = (Entry) entries.remove(key); if (e == null) @@ -521,7 +522,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * @param t the mappings that should be added to this map. * * @throws NullPointerException if t is null - **/ + */ public void putAll(Map t) { Iterator iter = t.entrySet().iterator(); while (iter.hasNext()) { @@ -572,7 +573,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * method is suitable for debugging purposes only. If a specific format is * required, use {@link #entrySet()}.{@link Set#iterator() iterator()} and * iterate over the entries in the map formatting them as appropriate. - **/ + */ public String toString() { StringBuffer buf = new StringBuffer(); buf.append('['); @@ -732,20 +733,20 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * on the same element. Essientially, if this value is negative (i.e. the * bit specified by {@link #REMOVED_MASK} is set), the current position * has been removed. If positive, remove can still be called. - **/ + */ private int returnType; /** * Holds the "current" position in the iterator. When pos.next is the * sentinel, we've reached the end of the list. - **/ + */ private Entry pos = sentinel; /** * Holds the expected modification count. If the actual modification * count of the map differs from this value, then a concurrent * modification has occurred. - **/ + */ private transient long expectedModCount = modCount; /** @@ -753,7 +754,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * they were added. The {@link #next()} method returns the type specified * by returnType which must be either {@link #KEY}, {@link * #VALUE}, or {@link #ENTRY}. - **/ + */ public OrderedIterator(int returnType) { //// Since this is a private inner class, nothing else should have //// access to the constructor. Since we know the rest of the outer @@ -774,7 +775,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * * @return true if there are more elements left to be * returned from the iterator; false otherwise. - **/ + */ public boolean hasNext() { return pos.next != sentinel; } @@ -789,7 +790,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * * @throws ConcurrentModificationException if a modification occurs in * the underlying map. - **/ + */ public Object next() { if (modCount != expectedModCount) { throw new ConcurrentModificationException(); @@ -826,7 +827,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * * @throws ConcurrentModificationException if a modification occurs in * the underlying map. - **/ + */ public void remove() { if ((returnType & REMOVED_MASK) != 0) { throw new IllegalStateException("remove() must follow next()"); @@ -891,7 +892,7 @@ public class SequencedHashMap implements Map, Cloneable, Externalizable { * * @throws ArrayIndexOutOfBoundsException if the specified index is * < 0 or > the size of the map. - **/ + */ private Map.Entry getEntry(int index) { Entry pos = sentinel; diff --git a/src/java/org/apache/commons/collections/SetUtils.java b/src/java/org/apache/commons/collections/SetUtils.java index 468457cfb..d1e43d495 100644 --- a/src/java/org/apache/commons/collections/SetUtils.java +++ b/src/java/org/apache/commons/collections/SetUtils.java @@ -1,5 +1,5 @@ /* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/SetUtils.java,v 1.15 2003/08/31 17:26:44 scolebourne Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/SetUtils.java,v 1.16 2003/09/09 22:28:36 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -64,6 +64,7 @@ import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; +import org.apache.commons.collections.decorators.OrderedSet; import org.apache.commons.collections.decorators.PredicatedSet; import org.apache.commons.collections.decorators.PredicatedSortedSet; import org.apache.commons.collections.decorators.TransformedSet; @@ -76,7 +77,7 @@ import org.apache.commons.collections.decorators.TypedSortedSet; * and {@link SortedSet} instances. * * @since Commons Collections 2.1 - * @version $Revision: 1.15 $ $Date: 2003/08/31 17:26:44 $ + * @version $Revision: 1.16 $ $Date: 2003/09/09 22:28:36 $ * * @author Paul Jack * @author Stephen Colebourne @@ -87,7 +88,7 @@ public class SetUtils { /** * An empty unmodifiable set. - * This uses the {@link Collections Collections} implementation + * This uses the {@link Collections} implementation * and is provided for completeness. */ public static final Set EMPTY_SET = Collections.EMPTY_SET; @@ -247,7 +248,7 @@ public class SetUtils { * Set. It is important not to use the original set after invoking this * method, as it is a backdoor for adding untransformed objects. * - * @param set the set to predicate, must not be null + * @param set the set to transform, must not be null * @param transformer the transformer for the set, must not be null * @return a transformed set backed by the given set * @throws IllegalArgumentException if the Set or Transformer is null @@ -256,6 +257,22 @@ public class SetUtils { return TransformedSet.decorate(set, transformer); } + + /** + * Returns a set that maintains the order of elements that are added + * backed by the given set. + *

+ * If an element is added twice, the order is determined by the first add. + * The order is observed through the iterator or toArray. + * + * @param set the set to order, must not be null + * @return an ordered set backed by the given set + * @throws IllegalArgumentException if the Set is null + */ + public static Set orderedSet(Set set) { + return OrderedSet.decorate(set); + } + //----------------------------------------------------------------------- /** * Returns a synchronized sorted set backed by the given sorted set. @@ -332,7 +349,7 @@ public class SetUtils { * Set. It is important not to use the original set after invoking this * method, as it is a backdoor for adding untransformed objects. * - * @param set the set to predicate, must not be null + * @param set the set to transform, must not be null * @param transformer the transformer for the set, must not be null * @return a transformed set backed by the given set * @throws IllegalArgumentException if the Set or Transformer is null diff --git a/src/java/org/apache/commons/collections/decorators/SequencedSet.java b/src/java/org/apache/commons/collections/decorators/OrderedSet.java similarity index 89% rename from src/java/org/apache/commons/collections/decorators/SequencedSet.java rename to src/java/org/apache/commons/collections/decorators/OrderedSet.java index 08c209cde..4cbd4fafb 100644 --- a/src/java/org/apache/commons/collections/decorators/SequencedSet.java +++ b/src/java/org/apache/commons/collections/decorators/OrderedSet.java @@ -1,5 +1,5 @@ /* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/decorators/Attic/SequencedSet.java,v 1.2 2003/08/31 17:24:46 scolebourne Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/java/org/apache/commons/collections/decorators/Attic/OrderedSet.java,v 1.1 2003/09/09 22:28:35 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -64,8 +64,8 @@ import java.util.List; import java.util.Set; /** - * SequencedSet decorates another Set - * to ensure that the order of addition is retained and used by the iterator. + * Decorates a Set to ensure that the order of addition + * is retained and used by the iterator. *

* If an object is added to the Set for a second time, it will remain in the * original position in the iteration. @@ -73,24 +73,24 @@ import java.util.Set; * The order can be observed via the iterator or toArray methods. * * @since Commons Collections 3.0 - * @version $Revision: 1.2 $ $Date: 2003/08/31 17:24:46 $ + * @version $Revision: 1.1 $ $Date: 2003/09/09 22:28:35 $ * * @author Stephen Colebourne * @author Henning P. Schmiedehausen */ -public class SequencedSet extends AbstractSetDecorator implements Set { +public class OrderedSet extends AbstractSetDecorator implements Set { /** Internal list to hold the sequence of objects */ protected final List setOrder = new ArrayList(); /** - * Factory method to create an unmodifiable set. + * Factory method to create an ordered set. * * @param set the set to decorate, must not be null * @throws IllegalArgumentException if set is null */ public static Set decorate(Set set) { - return new SequencedSet(set); + return new OrderedSet(set); } /** @@ -99,7 +99,7 @@ public class SequencedSet extends AbstractSetDecorator implements Set { * @param set the set to decorate, must not be null * @throws IllegalArgumentException if set is null */ - protected SequencedSet(Set set) { + protected OrderedSet(Set set) { super(set); setOrder.addAll(set); } @@ -111,7 +111,7 @@ public class SequencedSet extends AbstractSetDecorator implements Set { } public Iterator iterator() { - return new SequencedSetIterator(setOrder.iterator(), collection); + return new OrderedSetIterator(setOrder.iterator(), collection); } public boolean add(Object object) { @@ -178,14 +178,14 @@ public class SequencedSet extends AbstractSetDecorator implements Set { /** * Internal iterator handle remove. */ - protected static class SequencedSetIterator extends AbstractIteratorDecorator { + protected static class OrderedSetIterator extends AbstractIteratorDecorator { /** Object we iterate on */ protected final Collection set; /** Last object retrieved */ protected Object last; - private SequencedSetIterator(Iterator iterator, Collection set) { + private OrderedSetIterator(Iterator iterator, Collection set) { super(iterator); this.set = set; } diff --git a/src/test/org/apache/commons/collections/decorators/TestAll.java b/src/test/org/apache/commons/collections/decorators/TestAll.java index 45bb026af..9b16a692d 100644 --- a/src/test/org/apache/commons/collections/decorators/TestAll.java +++ b/src/test/org/apache/commons/collections/decorators/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/decorators/Attic/TestAll.java,v 1.8 2003/09/09 03:03:57 psteitz Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/decorators/Attic/TestAll.java,v 1.9 2003/09/09 22:28:36 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -65,7 +65,7 @@ import junit.framework.TestSuite; * Entry point for all collections decorators tests. * * @since Commons Collections 3.0 - * @version $Revision: 1.8 $ $Date: 2003/09/09 03:03:57 $ + * @version $Revision: 1.9 $ $Date: 2003/09/09 22:28:36 $ * * @author Stephen Colebourne */ @@ -87,7 +87,7 @@ public class TestAll extends TestCase { suite.addTest(TestFixedSizeMap.suite()); suite.addTest(TestFixedSizeSortedMap.suite()); - suite.addTest(TestSequencedSet.suite()); + suite.addTest(TestOrderedSet.suite()); suite.addTest(TestTransformedBag.suite()); suite.addTest(TestTransformedBuffer.suite()); diff --git a/src/test/org/apache/commons/collections/decorators/TestSequencedSet.java b/src/test/org/apache/commons/collections/decorators/TestOrderedSet.java similarity index 90% rename from src/test/org/apache/commons/collections/decorators/TestSequencedSet.java rename to src/test/org/apache/commons/collections/decorators/TestOrderedSet.java index 2abadd9a2..e26cf5290 100644 --- a/src/test/org/apache/commons/collections/decorators/TestSequencedSet.java +++ b/src/test/org/apache/commons/collections/decorators/TestOrderedSet.java @@ -1,5 +1,5 @@ /* - * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/decorators/Attic/TestSequencedSet.java,v 1.3 2003/08/31 17:28:42 scolebourne Exp $ + * $Header: /home/jerenkrantz/tmp/commons/commons-convert/cvs/home/cvs/jakarta-commons//collections/src/test/org/apache/commons/collections/decorators/Attic/TestOrderedSet.java,v 1.1 2003/09/09 22:28:36 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 @@ -67,32 +67,32 @@ import junit.framework.TestSuite; import org.apache.commons.collections.TestSet; /** - * Extension of {@link TestSet} for exercising the {@link SequencedSet} + * Extension of {@link TestSet} for exercising the {@link OrderedSet} * implementation. * * @since Commons Collections 3.0 - * @version $Revision: 1.3 $ $Date: 2003/08/31 17:28:42 $ + * @version $Revision: 1.1 $ $Date: 2003/09/09 22:28:36 $ * * @author Henning P. Schmiedehausen * @author Stephen Colebourne */ -public class TestSequencedSet extends TestSet { +public class TestOrderedSet extends TestSet { - public TestSequencedSet(String testName) { + public TestOrderedSet(String testName) { super(testName); } public static Test suite() { - return new TestSuite(TestSequencedSet.class); + return new TestSuite(TestOrderedSet.class); } public static void main(String args[]) { - String[] testCaseName = { TestSequencedSet.class.getName()}; + String[] testCaseName = { TestOrderedSet.class.getName()}; junit.textui.TestRunner.main(testCaseName); } public Set makeEmptySet() { - return SequencedSet.decorate(new HashSet()); + return OrderedSet.decorate(new HashSet()); } public Set setupSet() {