scolebourne 2003/12/02 15:36:12 Modified: collections/src/java/org/apache/commons/collections HashBag.java TreeBag.java DefaultMapBag.java collections/src/test/org/apache/commons/collections/bag TestAll.java AbstractTestBag.java Added: collections/src/java/org/apache/commons/collections/bag TreeBag.java AbstractMapBag.java HashBag.java collections/src/test/org/apache/commons/collections/bag TestTreeBag.java TestHashBag.java Log: Add new faster Bag implementations in bag subpackage Deprecate originals in main package Revision Changes Path 1.1 jakarta-commons/collections/src/java/org/apache/commons/collections/bag/TreeBag.java Index: TreeBag.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/bag/TreeBag.java,v 1.1 2003/12/02 23:36:12 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 2002-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 [EMAIL PROTECTED] * * 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 * <http://www.apache.org/>. * */ package org.apache.commons.collections.bag; import java.util.Collection; import java.util.Comparator; import java.util.SortedMap; import java.util.TreeMap; import org.apache.commons.collections.SortedBag; /** * Implements <code>SortedBag</code>, using a <code>TreeMap</code> to provide * the data storage. This is the standard implementation of a sorted bag. * <p> * Order will be maintained among the bag members and can be viewed through the * iterator. * * @since Commons Collections 3.0 * @version $Revision: 1.1 $ $Date: 2003/12/02 23:36:12 $ * * @author Chuck Burdick * @author Stephen Colebourne */ public class TreeBag extends AbstractMapBag implements SortedBag { /** * Constructs an empty <code>TreeBag</code>. */ public TreeBag() { super(new TreeMap()); } /** * Constructs an empty bag that maintains order on its unique * representative members according to the given [EMAIL PROTECTED] Comparator}. * * @param comparator the comparator to use */ public TreeBag(Comparator comparator) { super(new TreeMap(comparator)); } /** * Constructs a [EMAIL PROTECTED] Bag} containing all the members of the given * collection. * * @param coll the collection to copy into the bag */ public TreeBag(Collection coll) { this(); addAll(coll); } public Object first() { return ((SortedMap) getMap()).firstKey(); } public Object last() { return ((SortedMap) getMap()).lastKey(); } public Comparator comparator() { return ((SortedMap) getMap()).comparator(); } } 1.1 jakarta-commons/collections/src/java/org/apache/commons/collections/bag/AbstractMapBag.java Index: AbstractMapBag.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/bag/AbstractMapBag.java,v 1.1 2003/12/02 23:36:12 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 2002-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 [EMAIL PROTECTED] * * 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 * <http://www.apache.org/>. * */ package org.apache.commons.collections.bag; import java.lang.reflect.Array; import java.util.Collection; import java.util.Collections; import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.Map; import java.util.Set; import org.apache.commons.collections.Bag; /** * Abstract implementation of the [EMAIL PROTECTED] Bag} interface to simplify the creation * of subclass implementations. * <p> * Subclasses specify a Map implementation to use as the internal storage. * The map will be used to map bag elements to a number; the number represents * the number of occurrences of that element in the bag. * * @since Commons Collections 3.0 * @version $Revision: 1.1 $ $Date: 2003/12/02 23:36:12 $ * * @author Chuck Burdick * @author Michael A. Smith * @author Stephen Colebourne * @author Janek Bogucki */ public abstract class AbstractMapBag implements Bag { /** The map to use to store the data */ private final Map map; /** The current total size of the bag */ private int size; /** The modification count for fail fast iterators */ private transient int modCount; /** The modification count for fail fast iterators */ private transient Set uniqueSet; /** * Constructor that assigns the specified Map as the backing store. * The map must be empty. * * @param map the map to assign */ protected AbstractMapBag(Map map) { super(); this.map = map; } /** * Utility method for implementations to access the map that backs * this bag. Not intended for interactive use outside of * subclasses. */ protected Map getMap() { return map; } //----------------------------------------------------------------------- /** * Returns the number of elements in this bag. * * @return current size of the bag */ public int size() { return size; } /** * Returns true if the underlying map is empty. * * @return true if bag is empty */ public boolean isEmpty() { return map.isEmpty(); } /** * Returns the number of occurrence of the given element in this bag * by looking up its count in the underlying map. * * @param object the object to search for * @return the number of occurrences of the object, zero if not found */ public int getCount(Object object) { MutableInteger count = (MutableInteger) map.get(object); if (count != null) { return count.value; } return 0; } //----------------------------------------------------------------------- /** * Determines if the bag contains the given element by checking if the * underlying map contains the element as a key. * * @param object the object to search for * @return true if the bag contains the given element */ public boolean contains(Object object) { return map.containsKey(object); } /** * Determines if the bag contains the given elements. * * @param coll the collection to check against * @return <code>true</code> if the Bag contains all the collection */ public boolean containsAll(Collection coll) { if (coll instanceof Bag) { return containsAll((Bag) coll); } return containsAll(new HashBag(coll)); } /** * Returns <code>true</code> if the bag contains all elements in * the given collection, respecting cardinality. * * @param other the bag to check against * @return <code>true</code> if the Bag contains all the collection */ boolean containsAll(Bag other) { boolean result = true; Iterator it = other.uniqueSet().iterator(); while (it.hasNext()) { Object current = it.next(); boolean contains = getCount(current) >= ((Bag) other).getCount(current); result = result && contains; } return result; } //----------------------------------------------------------------------- /** * Gets an iterator over the bag elements. * Elements present in the Bag more than once will be returned repeatedly. * * @return the iterator */ public Iterator iterator() { return new BagIterator(this); // List result = new ArrayList(); // Iterator i = map.keySet().iterator(); // while (i.hasNext()) { // Object current = i.next(); // for (int index = getCount(current); index > 0; index--) { // result.add(current); // } // } // return new BagIterator(this, result.iterator()); } // static class BagIterator implements Iterator { // private AbstractMapBag parent; // private Iterator support; // private Object current; // private int mods; // private boolean canRemove; // // public BagIterator(AbstractMapBag parent, Iterator support) { // this.parent = parent; // this.support = support; // this.current = null; // this.mods = parent.modCount; // this.canRemove = false; // } // // public boolean hasNext() { // return support.hasNext(); // } // // public Object next() { // if (parent.modCount != mods) { // throw new ConcurrentModificationException(); // } // current = support.next(); // canRemove = true; // return current; // } // // public void remove() { // if (parent.modCount != mods) { // throw new ConcurrentModificationException(); // } // if (canRemove == false) { // throw new IllegalStateException(); // } // support.remove(); // parent.remove(current, 1); // canRemove = false; // mods++; // } // } static class BagIterator implements Iterator { private AbstractMapBag parent; private Iterator entryIterator; private Map.Entry current; private int itemCount; private final int mods; private boolean canRemove; public BagIterator(AbstractMapBag parent) { this.parent = parent; this.entryIterator = parent.map.entrySet().iterator(); this.current = null; this.mods = parent.modCount; this.canRemove = false; } public boolean hasNext() { return (itemCount > 0 || entryIterator.hasNext()); } public Object next() { if (parent.modCount != mods) { throw new ConcurrentModificationException(); } if (itemCount == 0) { current = (Map.Entry) entryIterator.next(); itemCount = ((MutableInteger) current.getValue()).value; } canRemove = true; itemCount--; return current.getKey(); } public void remove() { if (parent.modCount != mods) { throw new ConcurrentModificationException(); } if (canRemove == false) { throw new IllegalStateException(); } MutableInteger mut = (MutableInteger) current.getValue(); if (mut.value > 0) { mut.value--; parent.size--; } else { entryIterator.remove(); } canRemove = false; } } //----------------------------------------------------------------------- /** * Adds a new element to the bag, incrementing its count in the underlying map. * * @param object the object to add * @return <code>true</code> if the object was not already in the <code>uniqueSet</code> */ public boolean add(Object object) { return add(object, 1); } /** * Adds a new element to the bag, incrementing its count in the map. * * @param object the object to search for * @param nCopies the number of copies to add * @return <code>true</code> if the object was not already in the <code>uniqueSet</code> */ public boolean add(Object object, int nCopies) { modCount++; if (nCopies > 0) { MutableInteger mut = (MutableInteger) map.get(object); size += nCopies; if (mut == null) { map.put(object, new MutableInteger(nCopies)); return true; } else { mut.value += nCopies; return false; } } else { return false; } } /** * Invokes [EMAIL PROTECTED] #add(Object)} for each element in the given collection. * * @param coll the collection to add * @return <code>true</code> if this call changed the bag */ public boolean addAll(Collection coll) { boolean changed = false; Iterator i = coll.iterator(); while (i.hasNext()) { boolean added = add(i.next()); changed = changed || added; } return changed; } //----------------------------------------------------------------------- /** * Clears the bag by clearing the underlying map. */ public void clear() { modCount++; map.clear(); size = 0; } /** * Removes one copy of the specified object from the bag. * * @param object the object to remove * @return true if the bag changed */ public boolean remove(Object object) { return remove(object, getCount(object)); } /** * Removes a specified number of copies of an object from the bag. * * @param object the object to remove * @param nCopies the number of copies to remove * @return true if the bag changed */ public boolean remove(Object object, int nCopies) { MutableInteger mut = (MutableInteger) map.get(object); if (mut == null) { return false; } if (nCopies <= 0) { return false; } modCount++; if (nCopies < mut.value) { mut.value -= nCopies; size -= nCopies; } else { map.remove(object); size -= mut.value; } return true; } /** * Removes objects from the bag according to their count in the specified collection. * * @param coll the collection to use * @return true if the bag changed */ public boolean removeAll(Collection coll) { boolean result = false; if (coll != null) { Iterator i = coll.iterator(); while (i.hasNext()) { boolean changed = remove(i.next(), 1); result = result || changed; } } return result; } /** * Remove any members of the bag that are not in the given * bag, respecting cardinality. * * @param coll the collection to retain * @return true if this call changed the collection */ public boolean retainAll(Collection coll) { if (coll instanceof Bag) { return retainAll((Bag) coll); } return retainAll(new HashBag(coll)); } /** * Remove any members of the bag that are not in the given * bag, respecting cardinality. * @see #retainAll(Collection) * * @param other the bag to retain * @return <code>true</code> if this call changed the collection */ boolean retainAll(Bag other) { boolean result = false; Bag excess = new HashBag(); Iterator i = uniqueSet().iterator(); while (i.hasNext()) { Object current = i.next(); int myCount = getCount(current); int otherCount = other.getCount(current); if (1 <= otherCount && otherCount <= myCount) { excess.add(current, myCount - otherCount); } else { excess.add(current, myCount); } } if (!excess.isEmpty()) { result = removeAll(excess); } return result; } //----------------------------------------------------------------------- /** * Mutable integer class for storing the data */ static class MutableInteger { int value; MutableInteger(int value) { this.value = value; } } //----------------------------------------------------------------------- /** * Returns an array of all of this bag's elements. * * @return an array of all of this bag's elements */ public Object[] toArray() { Object[] result = new Object[size()]; int i = 0; Iterator it = map.keySet().iterator(); while (it.hasNext()) { Object current = it.next(); for (int index = getCount(current); index > 0; index--) { result[i++] = current; } } return result; } /** * Returns an array of all of this bag's elements. * * @param array the array to populate * @return an array of all of this bag's elements */ public Object[] toArray(Object[] array) { int size = size(); if (array.length < size) { array = (Object[]) Array.newInstance(array.getClass().getComponentType(), size); } int i = 0; Iterator it = map.keySet().iterator(); while (it.hasNext()) { Object current = it.next(); for (int index = getCount(current); index > 0; index--) { array[i++] = current; } } if (array.length > size) { array[size] = null; } return array; } /** * Returns an unmodifiable view of the underlying map's key set. * * @return the set of unique elements in this bag */ public Set uniqueSet() { if (uniqueSet == null) { uniqueSet = Collections.unmodifiableSet(map.keySet()); } return uniqueSet; } //----------------------------------------------------------------------- /** * Returns true if the given object is not null, has the precise type * of this bag, and contains the same number of occurrences of all the * same elements. * * @param object the object to test for equality * @return true if that object equals this bag */ public boolean equals(Object object) { if (object == this) { return true; } return (object != null && object.getClass().equals(this.getClass()) && ((AbstractMapBag) object).map.equals(this.map)); } /** * Returns the hash code of the underlying map. * * @return the hash code of the underlying map */ public int hashCode() { return map.hashCode(); } /** * Implement a toString() method suitable for debugging. * * @return a debugging toString */ public String toString() { if (size() == 0) { return "[]"; } StringBuffer buf = new StringBuffer(); buf.append('['); Iterator it = uniqueSet().iterator(); while (it.hasNext()) { Object current = it.next(); int count = getCount(current); buf.append(count); buf.append(':'); buf.append(current); if (it.hasNext()) { buf.append(','); } } buf.append(']'); return buf.toString(); } } 1.1 jakarta-commons/collections/src/java/org/apache/commons/collections/bag/HashBag.java Index: HashBag.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/bag/HashBag.java,v 1.1 2003/12/02 23:36:12 scolebourne Exp $ * ==================================================================== * * The Apache Software License, Version 1.1 * * Copyright (c) 2002-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 [EMAIL PROTECTED] * * 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 * <http://www.apache.org/>. * */ package org.apache.commons.collections.bag; import java.util.Collection; import java.util.HashMap; import org.apache.commons.collections.Bag; /** * Implements <code>Bag</code>, using a <code>HashMap</code> to provide the * data storage. This is the standard implementation of a bag. * * @since Commons Collections 3.0 * @version $Revision: 1.1 $ $Date: 2003/12/02 23:36:12 $ * * @author Chuck Burdick * @author Stephen Colebourne */ public class HashBag extends AbstractMapBag implements Bag { /** * Constructs an empty <Code>HashBag</Code>. */ public HashBag() { super(new HashMap()); } /** * Constructs a [EMAIL PROTECTED] Bag} containing all the members of the given collection. * * @param coll a collection to copy into this bag */ public HashBag(Collection coll) { this(); addAll(coll); } } 1.10 +3 -2 jakarta-commons/collections/src/java/org/apache/commons/collections/HashBag.java Index: HashBag.java =================================================================== RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/HashBag.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- HashBag.java 31 Aug 2003 17:26:44 -0000 1.9 +++ HashBag.java 2 Dec 2003 23:36:12 -0000 1.10 @@ -63,6 +63,7 @@ /** * A [EMAIL PROTECTED] Bag} that is backed by a [EMAIL PROTECTED] HashMap}. * + * @deprecated Moved to bag subpackage. Due to be removed in v4.0. * @since Commons Collections 2.0 * @version $Revision$ $Date$ * 1.10 +3 -2 jakarta-commons/collections/src/java/org/apache/commons/collections/TreeBag.java Index: TreeBag.java =================================================================== RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/TreeBag.java,v retrieving revision 1.9 retrieving revision 1.10 diff -u -r1.9 -r1.10 --- TreeBag.java 31 Aug 2003 17:26:44 -0000 1.9 +++ TreeBag.java 2 Dec 2003 23:36:12 -0000 1.10 @@ -67,6 +67,7 @@ * Order will be maintained among the unique representative * members. * + * @deprecated Moved to bag subpackage. Due to be removed in v4.0. * @since Commons Collections 2.0 * @version $Revision$ $Date$ * 1.11 +4 -3 jakarta-commons/collections/src/java/org/apache/commons/collections/DefaultMapBag.java Index: DefaultMapBag.java =================================================================== RCS file: /home/cvs/jakarta-commons/collections/src/java/org/apache/commons/collections/DefaultMapBag.java,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- DefaultMapBag.java 31 Aug 2003 17:26:44 -0000 1.10 +++ DefaultMapBag.java 2 Dec 2003 23:36:12 -0000 1.11 @@ -77,11 +77,12 @@ * The map will be used to map bag elements to a number; the number represents * the number of occurrences of that element in the bag. * + * @deprecated Moved to bag subpackage as AbstractMapBag. Due to be removed in v4.0. * @since Commons Collections 2.0 * @version $Revision$ $Date$ * * @author Chuck Burdick - * @author <a href="mailto:[EMAIL PROTECTED]">Michael A. Smith</a> + * @author Michael A. Smith * @author Stephen Colebourne * @author Janek Bogucki */ 1.2 +4 -2 jakarta-commons/collections/src/test/org/apache/commons/collections/bag/TestAll.java Index: TestAll.java =================================================================== RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bag/TestAll.java,v retrieving revision 1.1 retrieving revision 1.2 diff -u -r1.1 -r1.2 --- TestAll.java 16 Nov 2003 00:05:46 -0000 1.1 +++ TestAll.java 2 Dec 2003 23:36:12 -0000 1.2 @@ -83,10 +83,12 @@ public static Test suite() { TestSuite suite = new TestSuite(); + suite.addTest(TestHashBag.suite()); suite.addTest(TestPredicatedBag.suite()); suite.addTest(TestPredicatedSortedBag.suite()); suite.addTest(TestTransformedBag.suite()); suite.addTest(TestTransformedSortedBag.suite()); + suite.addTest(TestTreeBag.suite()); suite.addTest(TestTypedBag.suite()); suite.addTest(TestTypedSortedBag.suite()); 1.3 +84 -5 jakarta-commons/collections/src/test/org/apache/commons/collections/bag/AbstractTestBag.java Index: AbstractTestBag.java =================================================================== RCS file: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bag/AbstractTestBag.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- AbstractTestBag.java 18 Nov 2003 22:37:15 -0000 1.2 +++ AbstractTestBag.java 2 Dec 2003 23:36:12 -0000 1.3 @@ -61,6 +61,7 @@ import java.util.ConcurrentModificationException; import java.util.Iterator; import java.util.List; +import java.util.NoSuchElementException; import org.apache.commons.collections.AbstractTestObject; import org.apache.commons.collections.Bag; @@ -307,15 +308,93 @@ bag.add("A"); bag.add("A"); bag.add("B"); - Iterator i = bag.iterator(); - i.next(); + Iterator it = bag.iterator(); + it.next(); bag.remove("A"); try { - i.next(); + it.next(); fail("Should throw ConcurrentModificationException"); } catch (ConcurrentModificationException e) { // expected } } + public void testIteratorFailNoMore() { + Bag bag = makeBag(); + bag.add("A"); + bag.add("A"); + bag.add("B"); + Iterator it = bag.iterator(); + it.next(); + it.next(); + it.next(); + try { + it.next(); + fail("Should throw NoSuchElementException"); + } catch (NoSuchElementException ex) { + // expected + } + } + + public void testIteratorFailDoubleRemove() { + Bag bag = makeBag(); + bag.add("A"); + bag.add("A"); + bag.add("B"); + Iterator it = bag.iterator(); + it.next(); + it.next(); + assertEquals(3, bag.size()); + it.remove(); + assertEquals(2, bag.size()); + try { + it.remove(); + fail("Should throw IllegalStateException"); + } catch (IllegalStateException ex) { + // expected + } + assertEquals(2, bag.size()); + it.next(); + it.remove(); + assertEquals(1, bag.size()); + } + + public void testToArray() { + Bag bag = makeBag(); + bag.add("A"); + bag.add("A"); + bag.add("B"); + bag.add("B"); + bag.add("C"); + Object[] array = bag.toArray(); + int a = 0, b = 0, c = 0; + for (int i = 0; i < array.length; i++) { + a += (array[i].equals("A") ? 1 : 0); + b += (array[i].equals("B") ? 1 : 0); + c += (array[i].equals("C") ? 1 : 0); + } + assertEquals(2, a); + assertEquals(2, b); + assertEquals(1, c); + } + + public void testToArrayPopulate() { + Bag bag = makeBag(); + bag.add("A"); + bag.add("A"); + bag.add("B"); + bag.add("B"); + bag.add("C"); + String[] array = (String[]) bag.toArray(new String[0]); + int a = 0, b = 0, c = 0; + for (int i = 0; i < array.length; i++) { + a += (array[i].equals("A") ? 1 : 0); + b += (array[i].equals("B") ? 1 : 0); + c += (array[i].equals("C") ? 1 : 0); + } + assertEquals(2, a); + assertEquals(2, b); + assertEquals(1, c); + } + } 1.1 jakarta-commons/collections/src/test/org/apache/commons/collections/bag/TestTreeBag.java Index: TestTreeBag.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bag/TestTreeBag.java,v 1.1 2003/12/02 23:36:12 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 [EMAIL PROTECTED] * * 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 * <http://www.apache.org/>. * */ package org.apache.commons.collections.bag; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.collections.Bag; import org.apache.commons.collections.SortedBag; /** * Extension of [EMAIL PROTECTED] TestBag} for exercising the [EMAIL PROTECTED] TreeBag} * implementation. * * @version $Revision: 1.1 $ $Date: 2003/12/02 23:36:12 $ * * @author Chuck Burdick */ public class TestTreeBag extends AbstractTestBag { public TestTreeBag(String testName) { super(testName); } public static Test suite() { return new TestSuite(TestTreeBag.class); } public static void main(String args[]) { String[] testCaseName = { TestTreeBag.class.getName() }; junit.textui.TestRunner.main(testCaseName); } public Bag makeBag() { return new TreeBag(); } public SortedBag setupBag() { SortedBag bag = (SortedBag)makeBag(); bag.add("C"); bag.add("A"); bag.add("B"); bag.add("D"); return bag; } public void testOrdering() { Bag bag = setupBag(); assertEquals("Should get elements in correct order", "A", bag.toArray()[0]); assertEquals("Should get elements in correct order", "B", bag.toArray()[1]); assertEquals("Should get elements in correct order", "C", bag.toArray()[2]); assertEquals("Should get first key", "A", ((SortedBag)bag).first()); assertEquals("Should get last key", "D", ((SortedBag)bag).last()); } } 1.1 jakarta-commons/collections/src/test/org/apache/commons/collections/bag/TestHashBag.java Index: TestHashBag.java =================================================================== /* * $Header: /home/cvs/jakarta-commons/collections/src/test/org/apache/commons/collections/bag/TestHashBag.java,v 1.1 2003/12/02 23:36:12 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 [EMAIL PROTECTED] * * 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 * <http://www.apache.org/>. * */ package org.apache.commons.collections.bag; import junit.framework.Test; import junit.framework.TestSuite; import org.apache.commons.collections.Bag; /** * Extension of [EMAIL PROTECTED] TestBag} for exercising the [EMAIL PROTECTED] HashBag} * implementation. * * @version $Revision: 1.1 $ $Date: 2003/12/02 23:36:12 $ * * @author Chuck Burdick */ public class TestHashBag extends AbstractTestBag { public TestHashBag(String testName) { super(testName); } public static Test suite() { return new TestSuite(TestHashBag.class); } public static void main(String args[]) { String[] testCaseName = { TestHashBag.class.getName()}; junit.textui.TestRunner.main(testCaseName); } public Bag makeBag() { return new HashBag(); } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]