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 2005/05/15 20:30:49 UTC
svn commit: r170244 - in /jakarta/commons/proper/collections/trunk: ./
src/java/org/apache/commons/collections/list/
src/test/org/apache/commons/collections/list/
Author: scolebourne
Date: Sun May 15 11:30:49 2005
New Revision: 170244
URL: http://svn.apache.org/viewcvs?rev=170244&view=rev
Log:
Add GrowthList, an auto-grow on set/add list
bug 34171, including code from Paul Legato
Added:
jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/GrowthList.java (with props)
jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestGrowthList.java (with props)
Modified:
jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html
jakarta/commons/proper/collections/trunk/project.xml
jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/LazyList.java
jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestAll.java
Modified: jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html?rev=170244&r1=170243&r2=170244&view=diff
==============================================================================
--- jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html (original)
+++ jakarta/commons/proper/collections/trunk/RELEASE-NOTES.html Sun May 15 11:30:49 2005
@@ -43,6 +43,7 @@
<center><h3>NEW CLASSES</h3></center>
<ul>
<li>DefaultedMap - Returns a default value when the key is not found, without adding the default value to the map itself [30911]</li>
+<li>GrowthList - Decorator that causes set and indexed add to expand the list rather than throw IndexOutOfBoundsException [34171]</li>
<li>LoopingListIterator - When the end of the list is reached the iteration continues from the start [30166]</li>
</ul>
Modified: jakarta/commons/proper/collections/trunk/project.xml
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/project.xml?rev=170244&r1=170243&r2=170244&view=diff
==============================================================================
--- jakarta/commons/proper/collections/trunk/project.xml (original)
+++ jakarta/commons/proper/collections/trunk/project.xml Sun May 15 11:30:49 2005
@@ -222,6 +222,9 @@
<name>Guilhem Lavaux</name>
</contributor>
<contributor>
+ <name>Paul Legato</name>
+ </contributor>
+ <contributor>
<name>David Leppik</name>
</contributor>
<contributor>
Added: jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/GrowthList.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/GrowthList.java?rev=170244&view=auto
==============================================================================
--- jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/GrowthList.java (added)
+++ jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/GrowthList.java Sun May 15 11:30:49 2005
@@ -0,0 +1,185 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections.list;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * Decorates another <code>List</code> to make it seemlessly grow when
+ * indices larger than the list size are used on add and set,
+ * avoiding most IndexOutOfBoundsExceptions.
+ * <p>
+ * This class avoids errors by growing when a set or add method would
+ * normally throw an IndexOutOfBoundsException.
+ * Note that IndexOutOfBoundsException IS returned for invalid negative indices.
+ * <p>
+ * Trying to set or add to an index larger than the size will cause the list
+ * to grow (using <code>null</code> elements). Clearly, care must be taken
+ * not to use excessively large indices, as the internal list will grow to
+ * match.
+ * <p>
+ * Trying to use any method other than add or set with an invalid inde will
+ * call the underlying list and probably result in an IndexOutOfBoundsException.
+ * <p>
+ * Take care when using this list with <code>null</code> values, as
+ * <code>null</code> is the value added when growing the list.
+ * <p>
+ * All sub-lists will access the underlying list directly, and will throw
+ * IndexOutOfBoundsExceptions.
+ * <p>
+ * This class differs from {@link LazyList} because here growth occurs on
+ * set and add, where <code>LazyList</code> grows on get. However, they
+ * could easily be used together by decorating twice.
+ *
+ * @see LazyList
+ * @since Commons Collections 3.2
+ * @version $Revision: 155406 $ $Date$
+ *
+ * @author Stephen Colebourne
+ * @author Paul Legato
+ */
+public class GrowthList extends AbstractSerializableListDecorator {
+
+ /** Serialization version */
+ private static final long serialVersionUID = -3620001881672L;
+
+ /**
+ * Factory method to create a growth list.
+ *
+ * @param list the list to decorate, must not be null
+ * @throws IllegalArgumentException if list is null
+ */
+ public static List decorate(List list) {
+ return new GrowthList(list);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Constructor that uses an ArrayList internally.
+ */
+ public GrowthList() {
+ super(new ArrayList());
+ }
+
+ /**
+ * Constructor that uses an ArrayList internally.
+ *
+ * @param initialSize the initial size of the ArrayList
+ * @throws IllegalArgumentException if initial size is invalid
+ */
+ public GrowthList(int initialSize) {
+ super(new ArrayList(initialSize));
+ }
+
+ /**
+ * Constructor that wraps (not copies).
+ *
+ * @param list the list to decorate, must not be null
+ * @throws IllegalArgumentException if list is null
+ */
+ protected GrowthList(List list) {
+ super(list);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Decorate the add method to perform the growth behaviour.
+ * <p>
+ * If the requested index is greater than the current size, the list will
+ * grow to the new size. Indices between the old size and the requested
+ * size will be filled with <code>null</code>.
+ * <p>
+ * If the index is less than the current size, the value will be added to
+ * the underlying list directly.
+ * If the index is less than zero, the underlying list is called, which
+ * will probably throw an IndexOutOfBoundsException.
+ *
+ * @param index the index to add at
+ * @param element the object to add at the specified index
+ * @throws UnsupportedOperationException if the underlying list doesn't implement set
+ * @throws ClassCastException if the underlying list rejects the element
+ * @throws IllegalArgumentException if the underlying list rejects the element
+ */
+ public void add(int index, Object element) {
+ int size = getList().size();
+ if (index > size) {
+ getList().addAll(Collections.nCopies(index - size, null));
+ }
+ getList().add(index, element);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Decorate the addAll method to perform the growth behaviour.
+ * <p>
+ * If the requested index is greater than the current size, the list will
+ * grow to the new size. Indices between the old size and the requested
+ * size will be filled with <code>null</code>.
+ * <p>
+ * If the index is less than the current size, the values will be added to
+ * the underlying list directly.
+ * If the index is less than zero, the underlying list is called, which
+ * will probably throw an IndexOutOfBoundsException.
+ *
+ * @param index the index to add at
+ * @param coll the collection to add at the specified index
+ * @return true if the list changed
+ * @throws UnsupportedOperationException if the underlying list doesn't implement set
+ * @throws ClassCastException if the underlying list rejects the element
+ * @throws IllegalArgumentException if the underlying list rejects the element
+ */
+ public boolean addAll(int index, Collection coll) {
+ int size = getList().size();
+ boolean result = false;
+ if (index > size) {
+ getList().addAll(Collections.nCopies(index - size, null));
+ result = true;
+ }
+ return (getList().addAll(index, coll) | result);
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Decorate the set method to perform the growth behaviour.
+ * <p>
+ * If the requested index is greater than the current size, the list will
+ * grow to the new size. Indices between the old size and the requested
+ * size will be filled with <code>null</code>.
+ * <p>
+ * If the index is less than the current size, the value will be set onto
+ * the underlying list directly.
+ * If the index is less than zero, the underlying list is called, which
+ * will probably throw an IndexOutOfBoundsException.
+ *
+ * @param index the index to set
+ * @param element the object to set at the specified index
+ * @return the object previously at that index
+ * @throws UnsupportedOperationException if the underlying list doesn't implement set
+ * @throws ClassCastException if the underlying list rejects the element
+ * @throws IllegalArgumentException if the underlying list rejects the element
+ */
+ public Object set(int index, Object element) {
+ int size = getList().size();
+ if (index >= size) {
+ getList().addAll(Collections.nCopies((index - size) + 1, null));
+ }
+ return getList().set(index, element);
+ }
+
+}
Propchange: jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/GrowthList.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/GrowthList.java
------------------------------------------------------------------------------
svn:keywords = "author date id revision"
Modified: jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/LazyList.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/LazyList.java?rev=170244&r1=170243&r2=170244&view=diff
==============================================================================
--- jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/LazyList.java (original)
+++ jakarta/commons/proper/collections/trunk/src/java/org/apache/commons/collections/list/LazyList.java Sun May 15 11:30:49 2005
@@ -46,8 +46,13 @@
* instance is the fourth element in the list. The first, second,
* and third element are all set to <code>null</code>.
* <p>
+ * This class differs from {@link GrowthList} because here growth occurs on
+ * get, where <code>GrowthList</code> grows on set and add. However, they
+ * could easily be used together by decorating twice.
+ * <p>
* This class is Serializable from Commons Collections 3.1.
*
+ * @see GrowthList
* @since Commons Collections 3.0
* @version $Revision$ $Date$
*
Modified: jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestAll.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestAll.java?rev=170244&r1=170243&r2=170244&view=diff
==============================================================================
--- jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestAll.java (original)
+++ jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestAll.java Sun May 15 11:30:49 2005
@@ -46,6 +46,7 @@
suite.addTest(TestTreeList.suite());
suite.addTest(TestFixedSizeList.suite());
+ suite.addTest(TestGrowthList.suite());
suite.addTest(TestPredicatedList.suite());
suite.addTest(TestSetUniqueList.suite());
suite.addTest(TestSynchronizedList.suite());
Added: jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestGrowthList.java
URL: http://svn.apache.org/viewcvs/jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestGrowthList.java?rev=170244&view=auto
==============================================================================
--- jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestGrowthList.java (added)
+++ jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestGrowthList.java Sun May 15 11:30:49 2005
@@ -0,0 +1,175 @@
+/*
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.collections.list;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+
+/**
+ * Extension of {@link TestList} for exercising the {@link GrowthList}.
+ *
+ * @since Commons Collections 3.2
+ * @version $Revision: 155406 $ $Date$
+ *
+ * @author Stephen Colebourne
+ */
+public class TestGrowthList extends AbstractTestList {
+
+ public TestGrowthList(String testName) {
+ super(testName);
+ }
+
+ public static Test suite() {
+ return new TestSuite(TestGrowthList.class);
+ }
+
+ public static void main(String args[]) {
+ String[] testCaseName = { TestGrowthList.class.getName()};
+ junit.textui.TestRunner.main(testCaseName);
+ }
+
+ public List makeEmptyList() {
+ return new GrowthList();
+ }
+
+ public List makeFullList() {
+ List list = new ArrayList();
+ list.addAll(Arrays.asList(getFullElements()));
+ return GrowthList.decorate(list);
+ }
+
+ //-----------------------------------------------------------------------
+ public void testGrowthAdd() {
+ Integer one = new Integer(1);
+ GrowthList grower = new GrowthList();
+ assertEquals(0, grower.size());
+ grower.add(1, one);
+ assertEquals(2, grower.size());
+ assertEquals(null, grower.get(0));
+ assertEquals(one, grower.get(1));
+ }
+
+ public void testGrowthAddAll() {
+ Integer one = new Integer(1);
+ Integer two = new Integer(2);
+ Collection coll = new ArrayList();
+ coll.add(one);
+ coll.add(two);
+ GrowthList grower = new GrowthList();
+ assertEquals(0, grower.size());
+ grower.addAll(1, coll);
+ assertEquals(3, grower.size());
+ assertEquals(null, grower.get(0));
+ assertEquals(one, grower.get(1));
+ assertEquals(two, grower.get(2));
+ }
+
+ public void testGrowthSet1() {
+ Integer one = new Integer(1);
+ GrowthList grower = new GrowthList();
+ assertEquals(0, grower.size());
+ grower.set(1, one);
+ assertEquals(2, grower.size());
+ assertEquals(null, grower.get(0));
+ assertEquals(one, grower.get(1));
+ }
+
+ public void testGrowthSet2() {
+ Integer one = new Integer(1);
+ GrowthList grower = new GrowthList();
+ assertEquals(0, grower.size());
+ grower.set(0, one);
+ assertEquals(1, grower.size());
+ assertEquals(one, grower.get(0));
+ }
+
+ //-----------------------------------------------------------------------
+ /**
+ * Override.
+ */
+ public void testListAddByIndexBoundsChecking() {
+ List list;
+ Object element = getOtherElements()[0];
+ try {
+ list = makeEmptyList();
+ list.add(-1, element);
+ fail("List.add should throw IndexOutOfBoundsException [-1]");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Override.
+ */
+ public void testListAddByIndexBoundsChecking2() {
+ List list;
+ Object element = getOtherElements()[0];
+ try {
+ list = makeFullList();
+ list.add(-1, element);
+ fail("List.add should throw IndexOutOfBoundsException [-1]");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Override.
+ */
+ public void testListSetByIndexBoundsChecking() {
+ List list = makeEmptyList();
+ Object element = getOtherElements()[0];
+ try {
+ list.set(-1, element);
+ fail("List.set should throw IndexOutOfBoundsException [-1]");
+ } catch (IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ /**
+ * Override.
+ */
+ public void testListSetByIndexBoundsChecking2() {
+ List list = makeFullList();
+ Object element = getOtherElements()[0];
+ try {
+ list.set(-1, element);
+ fail("List.set should throw IndexOutOfBoundsException [-1]");
+ } catch(IndexOutOfBoundsException e) {
+ // expected
+ }
+ }
+
+ //-----------------------------------------------------------------------
+ public String getCompatibilityVersion() {
+ return "3.2";
+ }
+
+// public void testCreate() throws Exception {
+// resetEmpty();
+// writeExternalFormToDisk((java.io.Serializable) collection, "C:/commons/collections/data/test/GrowthList.emptyCollection.version3.2.obj");
+// resetFull();
+// writeExternalFormToDisk((java.io.Serializable) collection, "C:/commons/collections/data/test/GrowthList.fullCollection.version3.2.obj");
+// }
+
+}
Propchange: jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestGrowthList.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange: jakarta/commons/proper/collections/trunk/src/test/org/apache/commons/collections/list/TestGrowthList.java
------------------------------------------------------------------------------
svn:keywords = "author date id revision"
---------------------------------------------------------------------
To unsubscribe, e-mail: commons-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: commons-dev-help@jakarta.apache.org