You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by sc...@apache.org on 2003/09/20 18:57:47 UTC
cvs commit: jakarta-commons/collections/src/test/org/apache/commons/collections/decorators TestOrderedSet.java
scolebourne 2003/09/20 09:57:47
Modified: collections/src/java/org/apache/commons/collections/decorators
OrderedSet.java
collections/src/test/org/apache/commons/collections/decorators
TestOrderedSet.java
Log:
Enhance OrderedSet to support List like functions
Revision Changes Path
1.2 +97 -7 jakarta-commons/collections/src/java/org/apache/commons/collections/decorators/OrderedSet.java
Index: OrderedSet.java
===================================================================
RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/decorators/OrderedSet.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- OrderedSet.java 9 Sep 2003 22:28:35 -0000 1.1
+++ OrderedSet.java 20 Sep 2003 16:57:47 -0000 1.2
@@ -59,6 +59,8 @@
import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
@@ -67,10 +69,17 @@
* Decorates a <code>Set</code> to ensure that the order of addition
* is retained and used by the iterator.
* <p>
- * If an object is added to the Set for a second time, it will remain in the
+ * If an object is added to the set for a second time, it will remain in the
* original position in the iteration.
+ * The order can be observed from the set via the iterator or toArray methods.
* <p>
- * The order can be observed via the iterator or toArray methods.
+ * The OrderedSet also has various useful direct methods. These include many
+ * from <code>List</code>, such as <code>get(int)</code>, <code>remove(int)</code>
+ * and <code>indexOf(int)</code>. An unmodifiable <code>List</code> view of
+ * the set can be obtained via <code>asList()</code>.
+ * <p>
+ * This class cannot implement the <code>List</code> interface directly as
+ * various interface methods (notably equals/hashCode) are incompatable with a set.
*
* @since Commons Collections 3.0
* @version $Revision$ $Date$
@@ -81,19 +90,36 @@
public class OrderedSet extends AbstractSetDecorator implements Set {
/** Internal list to hold the sequence of objects */
- protected final List setOrder = new ArrayList();
+ protected final List setOrder;
/**
* Factory method to create an ordered set.
+ * <p>
+ * An <code>ArrayList</code> is used to retain order.
*
* @param set the set to decorate, must not be null
* @throws IllegalArgumentException if set is null
*/
- public static Set decorate(Set set) {
+ public static OrderedSet decorate(Set set) {
return new OrderedSet(set);
}
/**
+ * Factory method to create an ordered set using the supplied list to retain order.
+ * <p>
+ * A <code>HashSet</code> is used for the set behaviour.
+ *
+ * @param list the list to decorate, must not be null
+ * @throws IllegalArgumentException if set is null
+ */
+ public static OrderedSet decorate(List list) {
+ Set set = new HashSet(list);
+ list.retainAll(set);
+
+ return new OrderedSet(set, list);
+ }
+
+ /**
* Constructor that wraps (not copies).
*
* @param set the set to decorate, must not be null
@@ -101,7 +127,34 @@
*/
protected OrderedSet(Set set) {
super(set);
- setOrder.addAll(set);
+ setOrder = new ArrayList(set);
+ }
+
+ /**
+ * Constructor that wraps (not copies) the Set and specifies the list to use.
+ * <p>
+ * The set and list must both be correctly initialised to the same elements.
+ *
+ * @param set the set to decorate, must not be null
+ * @param list the list to decorate, must not be null
+ * @throws IllegalArgumentException if set or list is null
+ */
+ protected OrderedSet(Set set, List list) {
+ super(set);
+ if (list == null) {
+ throw new IllegalArgumentException("List must not be null");
+ }
+ setOrder = list;
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Gets an unmodifiable view of the order of the Set.
+ *
+ * @return an unmodifiable list view
+ */
+ public List asList() {
+ return Collections.unmodifiableList(setOrder);
}
//-----------------------------------------------------------------------
@@ -175,6 +228,43 @@
return setOrder.toArray(a);
}
+ //-----------------------------------------------------------------------
+ public Object get(int index) {
+ return setOrder.get(index);
+ }
+
+ public int indexOf(Object object) {
+ return setOrder.indexOf(object);
+ }
+
+ public void add(int index, Object object) {
+ if (contains(object) == false) {
+ collection.add(object);
+ setOrder.add(index, object);
+ }
+ }
+
+ public boolean addAll(int index, Collection coll) {
+ boolean changed = false;
+ for (Iterator it = coll.iterator(); it.hasNext();) {
+ Object object = (Object) it.next();
+ if (contains(object) == false) {
+ collection.add(object);
+ setOrder.add(index, object);
+ index++;
+ changed = true;
+ }
+ }
+ return changed;
+ }
+
+ public Object remove(int index) {
+ Object obj = setOrder.remove(index);
+ remove(obj);
+ return obj;
+ }
+
+ //-----------------------------------------------------------------------
/**
* Internal iterator handle remove.
*/
1.2 +76 -2 jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/TestOrderedSet.java
Index: TestOrderedSet.java
===================================================================
RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/decorators/TestOrderedSet.java,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- TestOrderedSet.java 9 Sep 2003 22:28:36 -0000 1.1
+++ TestOrderedSet.java 20 Sep 2003 16:57:47 -0000 1.2
@@ -57,8 +57,10 @@
*/
package org.apache.commons.collections.decorators;
+import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
+import java.util.List;
import java.util.Set;
import junit.framework.Test;
@@ -134,6 +136,78 @@
for (int i = 0; i < 10; i += 2) {
assertEquals("Sequence is wrong", Integer.toString(i), it.next());
}
+ }
+
+ private static final Integer ZERO = new Integer(0);
+ private static final Integer ONE = new Integer(1);
+ private static final Integer TWO = new Integer(2);
+ private static final Integer THREE = new Integer(3);
+
+ public void testListAddRemove() {
+ OrderedSet set = (OrderedSet) makeEmptySet();
+ List view = set.asList();
+ set.add(ZERO);
+ set.add(ONE);
+ set.add(TWO);
+
+ assertEquals(3, set.size());
+ assertSame(ZERO, set.get(0));
+ assertSame(ONE, set.get(1));
+ assertSame(TWO, set.get(2));
+ assertEquals(3, view.size());
+ assertSame(ZERO, view.get(0));
+ assertSame(ONE, view.get(1));
+ assertSame(TWO, view.get(2));
+
+ assertEquals(0, set.indexOf(ZERO));
+ assertEquals(1, set.indexOf(ONE));
+ assertEquals(2, set.indexOf(TWO));
+
+ set.remove(1);
+ assertEquals(2, set.size());
+ assertSame(ZERO, set.get(0));
+ assertSame(TWO, set.get(1));
+ assertEquals(2, view.size());
+ assertSame(ZERO, view.get(0));
+ assertSame(TWO, view.get(1));
+ }
+
+ public void testListAddIndexed() {
+ OrderedSet set = (OrderedSet) makeEmptySet();
+ List view = set.asList();
+ set.add(ZERO);
+ set.add(TWO);
+
+ set.add(1, ONE);
+ assertEquals(3, set.size());
+ assertSame(ZERO, set.get(0));
+ assertSame(ONE, set.get(1));
+ assertSame(TWO, set.get(2));
+
+ set.add(0, ONE);
+ assertEquals(3, set.size());
+ assertSame(ZERO, set.get(0));
+ assertSame(ONE, set.get(1));
+ assertSame(TWO, set.get(2));
+
+ List list = new ArrayList();
+ list.add(ZERO);
+ list.add(TWO);
+
+ set.addAll(0, list);
+ assertEquals(3, set.size());
+ assertSame(ZERO, set.get(0));
+ assertSame(ONE, set.get(1));
+ assertSame(TWO, set.get(2));
+
+ list.add(0, THREE); // list = [3,0,2]
+ set.remove(TWO); // set = [0,1]
+ set.addAll(1, list);
+ assertEquals(4, set.size());
+ assertSame(ZERO, set.get(0));
+ assertSame(THREE, set.get(1));
+ assertSame(TWO, set.get(2));
+ assertSame(ONE, set.get(3));
}
}