Return-Path: Delivered-To: apmail-commons-commits-archive@locus.apache.org Received: (qmail 79538 invoked from network); 8 Nov 2007 12:22:29 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 8 Nov 2007 12:22:29 -0000 Received: (qmail 70723 invoked by uid 500); 8 Nov 2007 12:22:15 -0000 Delivered-To: apmail-commons-commits-archive@commons.apache.org Received: (qmail 70651 invoked by uid 500); 8 Nov 2007 12:22:15 -0000 Mailing-List: contact commits-help@commons.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@commons.apache.org Delivered-To: mailing list commits@commons.apache.org Received: (qmail 70642 invoked by uid 99); 8 Nov 2007 12:22:15 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 08 Nov 2007 04:22:15 -0800 X-ASF-Spam-Status: No, hits=-100.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.3] (HELO eris.apache.org) (140.211.11.3) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 08 Nov 2007 12:22:17 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 194811A9832; Thu, 8 Nov 2007 04:21:57 -0800 (PST) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r593144 [1/2] - in /commons/proper/collections/branches/collections_jdk5_branch: ./ src/java/org/apache/commons/collections/ src/test/org/apache/commons/collections/ Date: Thu, 08 Nov 2007 12:21:56 -0000 To: commits@commons.apache.org From: skestle@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20071108122157.194811A9832@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: skestle Date: Thu Nov 8 04:21:55 2007 New Revision: 593144 URL: http://svn.apache.org/viewvc?rev=593144&view=rev Log: Updated CollectionUtils and test. Probably 80-90% complete for generics. Very open to review / patches. Jira: COLLECTIONS-245 Added: commons/proper/collections/branches/collections_jdk5_branch/src/test/org/apache/commons/collections/MockTestCase.java Modified: commons/proper/collections/branches/collections_jdk5_branch/build.xml commons/proper/collections/branches/collections_jdk5_branch/project.xml commons/proper/collections/branches/collections_jdk5_branch/src/java/org/apache/commons/collections/CollectionUtils.java commons/proper/collections/branches/collections_jdk5_branch/src/test/org/apache/commons/collections/TestCollectionUtils.java Modified: commons/proper/collections/branches/collections_jdk5_branch/build.xml URL: http://svn.apache.org/viewvc/commons/proper/collections/branches/collections_jdk5_branch/build.xml?rev=593144&r1=593143&r2=593144&view=diff ============================================================================== --- commons/proper/collections/branches/collections_jdk5_branch/build.xml (original) +++ commons/proper/collections/branches/collections_jdk5_branch/build.xml Thu Nov 8 04:21:55 2007 @@ -86,10 +86,17 @@ - + + + + + + + + - + @@ -107,30 +114,30 @@ - - - + + + - + - + - + @@ -143,7 +150,7 @@ - + @@ -152,7 +159,7 @@ tofile="${build.classes}/META-INF/LICENSE.txt"/> - + @@ -164,14 +171,14 @@ - + - + - + @@ -285,12 +292,12 @@ optimize="false"> - + - + - - + + @@ -379,7 +386,7 @@ - + @@ -400,11 +407,13 @@ - + - + + + - - - - + + + + @@ -435,12 +444,12 @@ - + - + @@ -457,7 +466,7 @@ - + @@ -475,7 +484,7 @@ - + @@ -486,13 +495,13 @@ - + - + @@ -504,18 +513,20 @@ - + - + - + + + - - - - - + + + + + - + @@ -565,7 +576,7 @@ - + @@ -582,7 +593,7 @@ - + @@ -614,12 +625,12 @@ - + - - + + @@ -627,10 +638,10 @@ - + - + @@ -639,8 +650,8 @@ - - + + @@ -651,7 +662,7 @@ - + @@ -660,8 +671,8 @@ - - + + @@ -673,10 +684,10 @@ - + - + Modified: commons/proper/collections/branches/collections_jdk5_branch/project.xml URL: http://svn.apache.org/viewvc/commons/proper/collections/branches/collections_jdk5_branch/project.xml?rev=593144&r1=593143&r2=593144&view=diff ============================================================================== --- commons/proper/collections/branches/collections_jdk5_branch/project.xml (original) +++ commons/proper/collections/branches/collections_jdk5_branch/project.xml Thu Nov 8 04:21:55 2007 @@ -172,6 +172,10 @@ Robert Burrell Donkin rdonkin + + Stephen Kestle + skestle + Modified: commons/proper/collections/branches/collections_jdk5_branch/src/java/org/apache/commons/collections/CollectionUtils.java URL: http://svn.apache.org/viewvc/commons/proper/collections/branches/collections_jdk5_branch/src/java/org/apache/commons/collections/CollectionUtils.java?rev=593144&r1=593143&r2=593144&view=diff ============================================================================== --- commons/proper/collections/branches/collections_jdk5_branch/src/java/org/apache/commons/collections/CollectionUtils.java (original) +++ commons/proper/collections/branches/collections_jdk5_branch/src/java/org/apache/commons/collections/CollectionUtils.java Thu Nov 8 04:21:55 2007 @@ -36,7 +36,8 @@ /** * Provides utility methods and decorators for {@link Collection} instances. - * + * Method parameters will take {@link Iterable} objects when possible. + * * @since Commons Collections 1.0 * @version $Revision$ $Date$ * @@ -55,14 +56,16 @@ * @author Stephen Smith * @author Stephen Kestle */ +//TODO - note generic types for review in wiki - especially ones +//TODO - doc Cardinality Helpers public class CollectionUtils { - private static class CardinalityHelper { - final Map cardinalityA, cardinalityB; + private static class CardinalityHelper { + final Map cardinalityA, cardinalityB; - public CardinalityHelper(Collection a, Collection b) { - cardinalityA = getCardinalityMap(a); - cardinalityB = getCardinalityMap(b); + public CardinalityHelper(Iterable a, Iterable b) { + cardinalityA = CollectionUtils.getCardinalityMap(a); + cardinalityB = CollectionUtils.getCardinalityMap(b); } public final int max(Object obj) { @@ -90,28 +93,29 @@ } } - private static class SetOperationCardinalityHelper extends CardinalityHelper implements Iterable { - private final Set elements; - private final List newList; + private static class SetOperationCardinalityHelper extends CardinalityHelper implements Iterable { + private final Set elements; + private final List newList; - public SetOperationCardinalityHelper(Collection a, Collection b) { + public SetOperationCardinalityHelper(Iterable a, Iterable b) { super(a, b); - elements = new HashSet(a); - elements.addAll(b); - newList = new ArrayList(); + elements = new HashSet(); + addAll(elements, a); + addAll(elements, b); + newList = new ArrayList(); } - public Iterator iterator() { + public Iterator iterator() { return elements.iterator(); } - public void setCardinality(Object obj, int count) { + public void setCardinality(O obj, int count) { for (int i = 0; i < count; i++) { newList.add(obj); } } - public Collection list() { + public Collection list() { return newList; } @@ -127,7 +131,7 @@ * this purpose. However they could be cast to Set or List which might be * undesirable. This implementation only implements Collection. */ - public static final Collection EMPTY_COLLECTION = UnmodifiableCollection.decorate(new ArrayList()); + public static final Collection EMPTY_COLLECTION = UnmodifiableCollection.decorate(new ArrayList()); /** * CollectionUtils should not normally be instantiated. @@ -136,43 +140,62 @@ } /** - * Returns a {@link Collection} containing the union - * of the given {@link Collection}s. + * Returns the immutable EMPTY_COLLECTION with generic type safety. + * + * @see #EMPTY_COLLECTION + * @since 4.0 + */ + @SuppressWarnings("unchecked") + public static Collection emptyCollection() { + return EMPTY_COLLECTION; + } + + /** + * Returns a {@link Collection} containing the union of the given + * {@link Collection}s. *

- * The cardinality of each element in the returned {@link Collection} - * will be equal to the maximum of the cardinality of that element - * in the two given {@link Collection}s. - * - * @param a the first collection, must not be null - * @param b the second collection, must not be null - * @return the union of the two collections + * The cardinality of each element in the returned {@link Collection} will + * be equal to the maximum of the cardinality of that element in the two + * given {@link Collection}s. + * + * @param a the first collection, must not be null + * @param b the second collection, must not be null + * @param the generic type that is able to represent the types contained + * in both input collections. + * @param the generic type of the first input {@link Iterable}. + * @param the generic type of the second input {@link Iterable}. + * @return the union of the two collections * @see Collection#addAll */ - public static Collection union(final Collection a, final Collection b) { - SetOperationCardinalityHelper helper = new SetOperationCardinalityHelper(a, b); - for (Object obj : helper) { + public static Collection union(final Iterable a, final Iterable b) { + SetOperationCardinalityHelper helper = new SetOperationCardinalityHelper(a, b); + for (O obj : helper) { helper.setCardinality(obj, helper.max(obj)); } return helper.list(); } /** - * Returns a {@link Collection} containing the intersection - * of the given {@link Collection}s. + * Returns a {@link Collection} containing the intersection of the given + * {@link Collection}s. *

- * The cardinality of each element in the returned {@link Collection} - * will be equal to the minimum of the cardinality of that element - * in the two given {@link Collection}s. - * - * @param a the first collection, must not be null - * @param b the second collection, must not be null + * The cardinality of each element in the returned {@link Collection} will + * be equal to the minimum of the cardinality of that element in the two + * given {@link Collection}s. + * + * @param a the first collection, must not be null + * @param b the second collection, must not be null + * @param the generic type that is able to represent the types contained + * in both input collections. + * @param the generic type of the first input {@link Iterable}. + * @param the generic type of the second input {@link Iterable}. * @return the intersection of the two collections * @see Collection#retainAll * @see #containsAny */ - public static Collection intersection(final Collection a, final Collection b) { - SetOperationCardinalityHelper helper = new SetOperationCardinalityHelper(a, b); - for (Object obj : helper) { + public static Collection intersection(final Iterable a, final Iterable b) { + SetOperationCardinalityHelper helper = new SetOperationCardinalityHelper(a, b); + for (O obj : helper) { helper.setCardinality(obj, helper.min(obj)); } return helper.list(); @@ -182,22 +205,26 @@ * Returns a {@link Collection} containing the exclusive disjunction * (symmetric difference) of the given {@link Collection}s. *

- * The cardinality of each element e in the returned {@link Collection} - * will be equal to + * The cardinality of each element e in the returned + * {@link Collection} will be equal to * max(cardinality(e,a),cardinality(e,b)) - min(cardinality(e,a),cardinality(e,b)). *

* This is equivalent to * {@link #subtract subtract}({@link #union union(a,b)},{@link #intersection intersection(a,b)}) * or * {@link #union union}({@link #subtract subtract(a,b)},{@link #subtract subtract(b,a)}). - * - * @param a the first collection, must not be null - * @param b the second collection, must not be null + + * @param a the first collection, must not be null + * @param b the second collection, must not be null + * @param the generic type that is able to represent the types contained + * in both input collections. + * @param the generic type of the first input {@link Iterable}. + * @param the generic type of the second input {@link Iterable}. * @return the symmetric difference of the two collections */ - public static Collection disjunction(final Collection a, final Collection b) { - SetOperationCardinalityHelper helper = new SetOperationCardinalityHelper(a, b); - for (Object obj : helper) { + public static Collection disjunction(final Iterable a, final Iterable b) { + SetOperationCardinalityHelper helper = new SetOperationCardinalityHelper(a, b); + for (O obj : helper) { helper.setCardinality(obj, helper.max(obj) - helper.min(obj)); } return helper.list(); @@ -211,13 +238,18 @@ * * @param a the collection to subtract from, must not be null * @param b the collection to subtract, must not be null + * @param the generic type that is able to represent the types contained + * in both input collections. + * @param the generic type of the first input {@link Iterable}. + * @param the generic type of the second input {@link Iterable}. * @return a new collection with the results * @see Collection#removeAll */ - public static Collection subtract(final Collection a, final Collection b) { - ArrayList list = new ArrayList( a ); - for (Iterator it = b.iterator(); it.hasNext();) { - list.remove(it.next()); + public static Collection subtract(final Iterable a, final Iterable b) { + ArrayList list = new ArrayList(); + addAll(list, a); + for (O element : b) { + list.remove(element); } return list; } @@ -259,18 +291,24 @@ * Only those elements present in the collection will appear as * keys in the map. * - * @param coll the collection to get the cardinality map for, must not be null + * @param coll + * the collection to get the cardinality map for, must not be + * null + * @param + * the type of object in the input {@link Collection} + * @param + * the type of object in the returned {@link Map}. This is a + * super type of . * @return the populated cardinality map */ - public static Map getCardinalityMap(final Collection coll) { - Map count = new HashMap(); - for (Iterator it = coll.iterator(); it.hasNext();) { - Object obj = it.next(); - Integer c = (Integer) (count.get(obj)); + public static Map getCardinalityMap(final Iterable coll) { + Map count = new HashMap(); + for (I obj : coll) { + Integer c = count.get(obj); if (c == null) { - count.put(obj,INTEGER_ONE); + count.put(obj, INTEGER_ONE); } else { - count.put(obj,new Integer(c.intValue() + 1)); + count.put(obj, c + 1); } } return count; @@ -278,18 +316,18 @@ /** * Returns true iff a is a sub-collection of b, - * that is, iff the cardinality of e in a is less - * than or equal to the cardinality of e in b, - * for each element e in a. - * - * @param a the first (sub?) collection, must not be null - * @param b the second (super?) collection, must not be null + * that is, iff the cardinality of e in a is less than or + * equal to the cardinality of e in b, for each element e + * in a. + * + * @param a the first (sub?) collection, must not be null + * @param b the second (super?) collection, must not be null * @return true iff a is a sub-collection of b * @see #isProperSubCollection * @see Collection#containsAll */ - public static boolean isSubCollection(final Collection a, final Collection b) { - CardinalityHelper helper = new CardinalityHelper(a, b); + public static boolean isSubCollection(final Collection a, final Collection b) { + CardinalityHelper helper = new CardinalityHelper(a, b); for (Object obj : a) { if (helper.freqA(obj) > helper.freqB(obj)) { return false; @@ -319,8 +357,8 @@ * @see #isSubCollection * @see Collection#containsAll */ - public static boolean isProperSubCollection(final Collection a, final Collection b) { - return (a.size() < b.size()) && CollectionUtils.isSubCollection(a,b); + public static boolean isProperSubCollection(final Collection a, final Collection b) { + return (a.size() < b.size()) && CollectionUtils.isSubCollection(a, b); } /** @@ -335,11 +373,11 @@ * @param b the second collection, must not be null * @return true iff the collections contain the same elements with the same cardinalities. */ - public static boolean isEqualCollection(final Collection a, final Collection b) { + public static boolean isEqualCollection(final Collection a, final Collection b) { if(a.size() != b.size()) { return false; } - final CardinalityHelper helper = new CardinalityHelper(a, b); + final CardinalityHelper helper = new CardinalityHelper(a, b); if(helper.cardinalityA.size() != helper.cardinalityB.size()) { return false; } @@ -353,28 +391,29 @@ /** * Returns the number of occurrences of obj in coll. - * - * @param obj the object to find the cardinality of - * @param coll the collection to search + * + * @param obj the object to find the cardinality of + * @param coll the {@link Iterable} to search + * @param the type of object that the {@link Iterable} may contain. * @return the the number of occurrences of obj in coll */ - public static int cardinality(Object obj, final Collection coll) { + public static int cardinality(O obj, final Iterable coll) { if (coll instanceof Set) { - return (coll.contains(obj) ? 1 : 0); + return (((Set) coll).contains(obj) ? 1 : 0); } if (coll instanceof Bag) { - return ((Bag) coll).getCount(obj); + return ((Bag) coll).getCount(obj); } int count = 0; if (obj == null) { - for (Iterator it = coll.iterator();it.hasNext();) { - if (it.next() == null) { + for (Object element : coll) { + if (element == null) { count++; } } } else { - for (Iterator it = coll.iterator();it.hasNext();) { - if (obj.equals(it.next())) { + for (Object element : coll) { + if (obj.equals(element)) { count++; } } @@ -392,10 +431,9 @@ * @param predicate the predicate to use, may be null * @return the first element of the collection which matches the predicate or null if none could be found */ - public static Object find(Collection collection, Predicate predicate) { + public static T find(Collection collection, Predicate predicate) { if (collection != null && predicate != null) { - for (Iterator iter = collection.iterator(); iter.hasNext();) { - Object item = iter.next(); + for (T item : collection) { if (predicate.evaluate(item)) { return item; } @@ -403,35 +441,39 @@ } return null; } - - /** + + /** * Executes the given closure on each element in the collection. *

* If the input collection or closure is null, there is no change made. * - * @param collection the collection to get the input from, may be null - * @param closure the closure to perform, may be null + * @param collection + * the collection to get the input from, may be null + * @param closure + * the closure to perform, may be null */ - public static void forAllDo(Collection collection, Closure closure) { + public static void forAllDo(Collection collection, Closure closure) { if (collection != null && closure != null) { - for (Iterator it = collection.iterator(); it.hasNext();) { - closure.execute(it.next()); + for (T element : collection) { + closure.execute(element); } } } - /** + /** * Filter the collection by applying a Predicate to each element. If the * predicate returns false, remove the element. *

* If the input collection or predicate is null, there is no change made. * - * @param collection the collection to get the input from, may be null - * @param predicate the predicate to use as a filter, may be null + * @param collection + * the collection to get the input from, may be null + * @param predicate + * the predicate to use as a filter, may be null */ - public static void filter(Collection collection, Predicate predicate) { + public static void filter(Iterable collection, Predicate predicate) { if (collection != null && predicate != null) { - for (Iterator it = collection.iterator(); it.hasNext();) { + for (Iterator it = collection.iterator(); it.hasNext();) { if (predicate.evaluate(it.next()) == false) { it.remove(); } @@ -439,51 +481,56 @@ } } - /** + /** * Transform the collection by applying a Transformer to each element. *

* If the input collection or transformer is null, there is no change made. *

- * This routine is best for Lists, for which set() is used to do the - * transformations "in place." For other Collections, clear() and addAll() - * are used to replace elements. + * This routine is best for Lists, for which set() is used to do the + * transformations "in place." For other Collections, clear() and addAll() + * are used to replace elements. *

* If the input collection controls its input, such as a Set, and the - * Transformer creates duplicates (or are otherwise invalid), the - * collection may reduce in size due to calling this method. + * Transformer creates duplicates (or are otherwise invalid), the collection + * may reduce in size due to calling this method. * - * @param collection the collection to get the input from, may be null - * @param transformer the transformer to perform, may be null + * @param collection + * the {@link Iterable} to get the input from, may be null + * @param transformer + * the transformer to perform, may be null */ - public static void transform(Collection collection, Transformer transformer) { + public static void transform(Collection collection, Transformer transformer) { if (collection != null && transformer != null) { if (collection instanceof List) { - List list = (List) collection; - for (ListIterator it = list.listIterator(); it.hasNext();) { + List list = (List) collection; + for (ListIterator it = list.listIterator(); it.hasNext();) { it.set(transformer.transform(it.next())); } } else { - Collection resultCollection = collect(collection, transformer); + Collection resultCollection = collect(collection, transformer); collection.clear(); collection.addAll(resultCollection); } } } - /** - * Counts the number of elements in the input collection that match the predicate. + /** + * Counts the number of elements in the input collection that match the + * predicate. *

* A null collection or predicate matches no elements. * - * @param inputCollection the collection to get the input from, may be null - * @param predicate the predicate to use, may be null + * @param input + * the {@link Iterable} to get the input from, may be null + * @param predicate + * the predicate to use, may be null * @return the number of matches for the predicate in the collection */ - public static int countMatches(Collection inputCollection, Predicate predicate) { + public static int countMatches(Iterable input, Predicate predicate) { int count = 0; - if (inputCollection != null && predicate != null) { - for (Iterator it = inputCollection.iterator(); it.hasNext();) { - if (predicate.evaluate(it.next())) { + if (input != null && predicate != null) { + for (C o : input) { + if (predicate.evaluate(o)) { count++; } } @@ -491,19 +538,23 @@ return count; } - /** - * Answers true if a predicate is true for at least one element of a collection. + /** + * Answers true if a predicate is true for at least one element of a + * collection. *

* A null collection or predicate returns false. * - * @param collection the collection to get the input from, may be null - * @param predicate the predicate to use, may be null - * @return true if at least one element of the collection matches the predicate - */ - public static boolean exists(Collection collection, Predicate predicate) { - if (collection != null && predicate != null) { - for (Iterator it = collection.iterator(); it.hasNext();) { - if (predicate.evaluate(it.next())) { + * @param input + * the {@link Iterable} to get the input from, may be null + * @param predicate + * the predicate to use, may be null + * @return true if at least one element of the collection matches the + * predicate + */ + public static boolean exists(Iterable input, Predicate predicate) { + if (input != null && predicate != null) { + for (C o : input) { + if (predicate.evaluate(o)) { return true; } } @@ -511,112 +562,134 @@ return false; } - /** - * Selects all elements from input collection which match the given predicate - * into an output collection. + /** + * Selects all elements from input collection which match the given + * predicate into an output collection. *

* A null predicate matches no elements. * - * @param inputCollection the collection to get the input from, may not be null - * @param predicate the predicate to use, may be null + * @param inputCollection + * the collection to get the input from, may not be null + * @param predicate + * the predicate to use, may be null * @return the elements matching the predicate (new list) - * @throws NullPointerException if the input collection is null + * @throws NullPointerException + * if the input collection is null */ - public static Collection select(Collection inputCollection, Predicate predicate) { - ArrayList answer = new ArrayList(inputCollection.size()); - select(inputCollection, predicate, answer); - return answer; + public static Collection select(Collection inputCollection, Predicate predicate) { + return select(inputCollection, predicate, new ArrayList(inputCollection.size())); } - /** - * Selects all elements from input collection which match the given predicate - * and adds them to outputCollection. + /** + * Selects all elements from input collection which match the given + * predicate and adds them to outputCollection. *

- * If the input collection or predicate is null, there is no change to the + * If the input collection or predicate is null, there is no change to the * output collection. * - * @param inputCollection the collection to get the input from, may be null - * @param predicate the predicate to use, may be null - * @param outputCollection the collection to output into, may not be null + * @param inputCollection + * the collection to get the input from, may be null + * @param predicate + * the predicate to use, may be null + * @param outputCollection + * the collection to output into, may not be null */ - public static void select(Collection inputCollection, Predicate predicate, Collection outputCollection) { + public static Collection select(Collection inputCollection, Predicate predicate, Collection outputCollection) { if (inputCollection != null && predicate != null) { - for (Iterator iter = inputCollection.iterator(); iter.hasNext();) { - Object item = iter.next(); + for (I item : inputCollection) { if (predicate.evaluate(item)) { outputCollection.add(item); } } } + return outputCollection; } - + /** - * Selects all elements from inputCollection which don't match the given predicate - * into an output collection. + * Selects all elements from inputCollection which don't match the given + * predicate into an output collection. *

- * If the input predicate is null, the result is an empty list. + * If the input predicate is null, the result is an empty + * list. * - * @param inputCollection the collection to get the input from, may not be null - * @param predicate the predicate to use, may be null + * @param inputCollection + * the collection to get the input from, may not be null + * @param predicate + * the predicate to use, may be null * @return the elements not matching the predicate (new list) - * @throws NullPointerException if the input collection is null + * @throws NullPointerException + * if the input collection is null */ - public static Collection selectRejected(Collection inputCollection, Predicate predicate) { - ArrayList answer = new ArrayList(inputCollection.size()); - selectRejected(inputCollection, predicate, answer); - return answer; + public static Collection selectRejected(Collection inputCollection, Predicate predicate) { + return selectRejected(inputCollection, predicate, new ArrayList(inputCollection.size())); } - - /** - * Selects all elements from inputCollection which don't match the given predicate - * and adds them to outputCollection. + + /** + * Selects all elements from inputCollection which don't match the given + * predicate and adds them to outputCollection. *

- * If the input predicate is null, no elements are added to outputCollection. + * If the input predicate is null, no elements are added to + * outputCollection. * - * @param inputCollection the collection to get the input from, may be null - * @param predicate the predicate to use, may be null - * @param outputCollection the collection to output into, may not be null + * @param inputCollection + * the collection to get the input from, may be null + * @param predicate + * the predicate to use, may be null + * @param outputCollection + * the collection to output into, may not be null */ - public static void selectRejected(Collection inputCollection, Predicate predicate, Collection outputCollection) { + public static Collection selectRejected(Collection inputCollection, Predicate predicate, Collection outputCollection) { if (inputCollection != null && predicate != null) { - for (Iterator iter = inputCollection.iterator(); iter.hasNext();) { - Object item = iter.next(); + for (I item : inputCollection) { if (predicate.evaluate(item) == false) { outputCollection.add(item); } } } + return outputCollection; } - - /** - * Returns a new Collection consisting of the elements of inputCollection transformed - * by the given transformer. + + /** + * Returns a new Collection consisting of the elements of inputCollection + * transformed by the given transformer. *

* If the input transformer is null, the result is an empty list. * - * @param inputCollection the collection to get the input from, may not be null - * @param transformer the transformer to use, may be null + * @param inputCollection + * the collection to get the input from, may not be null + * @param transformer + * the transformer to use, may be null + * @param the type of object in the input collection + * @param the type of object in the output collection + * @param the output type of the transformer - this extends O. * @return the transformed result (new list) - * @throws NullPointerException if the input collection is null + * @throws NullPointerException + * if the input collection is null */ - public static Collection collect(Collection inputCollection, Transformer transformer) { - ArrayList answer = new ArrayList(inputCollection.size()); + public static Collection collect(Iterable inputCollection, Transformer transformer) { + ArrayList answer = new ArrayList(); collect(inputCollection, transformer, answer); return answer; } - - /** - * Transforms all elements from the inputIterator with the given transformer + + /** + * Transforms all elements from the inputIterator with the given transformer * and adds them to the outputCollection. *

- * If the input iterator or transformer is null, the result is an empty list. + * If the input iterator or transformer is null, the result is an empty + * list. * - * @param inputIterator the iterator to get the input from, may be null - * @param transformer the transformer to use, may be null + * @param inputIterator + * the iterator to get the input from, may be null + * @param transformer + * the transformer to use, may be null + * @param the type of object in the input collection + * @param the type of object in the output collection + * @param the output type of the transformer - this extends O. * @return the transformed result (new list) */ - public static Collection collect(Iterator inputIterator, Transformer transformer) { - ArrayList answer = new ArrayList(); + public static Collection collect(Iterator inputIterator, Transformer transformer) { + ArrayList answer = new ArrayList(); collect(inputIterator, transformer, answer); return answer; } @@ -631,10 +704,13 @@ * @param inputCollection the collection to get the input from, may be null * @param transformer the transformer to use, may be null * @param outputCollection the collection to output into, may not be null + * @param the type of object in the input collection + * @param the type of object in the output collection + * @param the output type of the transformer - this extends O. * @return the outputCollection with the transformed input added * @throws NullPointerException if the output collection is null */ - public static Collection collect(Collection inputCollection, final Transformer transformer, final Collection outputCollection) { + public static Collection collect(Iterable inputCollection, final Transformer transformer, final Collection outputCollection) { if (inputCollection != null) { return collect(inputCollection.iterator(), transformer, outputCollection); } @@ -651,14 +727,18 @@ * @param inputIterator the iterator to get the input from, may be null * @param transformer the transformer to use, may be null * @param outputCollection the collection to output into, may not be null + * @param the type of object in the input collection + * @param the type of object in the output collection + * @param the output type of the transformer - this extends O. * @return the outputCollection with the transformed input added * @throws NullPointerException if the output collection is null */ - public static Collection collect(Iterator inputIterator, final Transformer transformer, final Collection outputCollection) { + //TODO - deprecate and replace with IteratorIterable + public static Collection collect(Iterator inputIterator, final Transformer transformer, final Collection outputCollection) { if (inputIterator != null && transformer != null) { while (inputIterator.hasNext()) { - Object item = inputIterator.next(); - Object value = transformer.transform(item); + I item = inputIterator.next(); + T value = transformer.transform(item); outputCollection.add(value); } } @@ -675,23 +755,49 @@ * @throws NullPointerException if the collection is null * @since Commons Collections 3.2 */ - public static boolean addIgnoreNull(Collection collection, Object object) { + public static boolean addIgnoreNull(Collection collection, T object) { return (object == null ? false : collection.add(object)); } - + + /** + * Adds all elements in the {@link Iterable} to the given collection. If the + * {@link Iterable} is a {@link Collection} then it is cast and will be + * added using {@link Collection#addAll(Collection)} instead of iterating. + * + * @param collection + * the collection to add to, must not be null + * @param iterable + * the iterable of elements to add, must not be null + * @return a boolean indicating whether the collection has changed or not. + * @throws NullPointerException + * if the collection or iterator is null + */ + public static boolean addAll(Collection collection, Iterable iterable) { + if (iterable instanceof Collection) { + return collection.addAll((Collection) iterable); + } + return addAll(collection, iterable.iterator()); + } + /** * Adds all elements in the iteration to the given collection. * - * @param collection the collection to add to, must not be null - * @param iterator the iterator of elements to add, must not be null - * @throws NullPointerException if the collection or iterator is null + * @param collection + * the collection to add to, must not be null + * @param iterator + * the iterator of elements to add, must not be null + * @return a boolean indicating whether the collection has changed or not. + * @throws NullPointerException + * if the collection or iterator is null */ - public static void addAll(Collection collection, Iterator iterator) { + public static boolean addAll(Collection collection, Iterator iterator) { + boolean changed = false; while (iterator.hasNext()) { - collection.add(iterator.next()); + changed |= collection.add(iterator.next()); } + return changed; } - + /** * Adds all elements in the enumeration to the given collection. * @@ -699,26 +805,87 @@ * @param enumeration the enumeration of elements to add, must not be null * @throws NullPointerException if the collection or enumeration is null */ - public static void addAll(Collection collection, Enumeration enumeration) { + //TODO return boolean or collection - check other add() methods too. + public static void addAll(Collection collection, Enumeration enumeration) { while (enumeration.hasMoreElements()) { collection.add(enumeration.nextElement()); } - } - - /** + } + + /** * Adds all elements in the array to the given collection. * - * @param collection the collection to add to, must not be null - * @param elements the array of elements to add, must not be null - * @throws NullPointerException if the collection or array is null + * @param collection + * the collection to add to, must not be null + * @param elements + * the array of elements to add, must not be null + * @throws NullPointerException + * if the collection or array is null */ - public static void addAll(Collection collection, Object[] elements) { + public static void addAll(Collection collection, T[] elements) { for (int i = 0, size = elements.length; i < size; i++) { collection.add(elements[i]); } - } + } + + /** + * Returns the index-th value in {@link Iterator}, throwing + * IndexOutOfBoundsException if there is no such element. + * The Iterator is advanced to + * index (or to the end, if index exceeds the + * number of entries) as a side effect of this method. + * + * @param iterator the iterator to get a value from + * @param index the index to get + * @param the type of object in the {@link Iterator} + * @return the object at the specified index + * @throws IndexOutOfBoundsException if the index is invalid + * @throws IllegalArgumentException if the object type is invalid + */ + public static T get(Iterator iterator, int index) { + checkIndexBounds(index); + while (iterator.hasNext()) { + index--; + if (index == -1) { + return iterator.next(); + } + iterator.next(); + } + throw new IndexOutOfBoundsException("Entry does not exist: " + index); + } /** + * Ensures an index is not negative. + * @param index the index to check. + * @throws IndexOutOfBoundsException if the index is negative. + */ + private static void checkIndexBounds(int index) { + if (index < 0) { + throw new IndexOutOfBoundsException("Index cannot be negative: " + index); + } + } + + /** + * Returns the index-th value in the iterable's {@link Iterator}, throwing + * IndexOutOfBoundsException if there is no such element. + *

+ * If the {@link Iterable} is a {@link List}, then it will use {@link List#get(int)}. + * + * @param iterable the {@link Iterable} to get a value from + * @param index the index to get + * @param the type of object in the {@link Iterable}. + * @return the object at the specified index + * @throws IndexOutOfBoundsException if the index is invalid + */ + public static T get(Iterable iterable, int index) { + checkIndexBounds(index); + if (iterable instanceof List) { + return ((List) iterable).get(index); + } + return get(iterable.iterator(), index); + } + + /** * Returns the index-th value in object, throwing * IndexOutOfBoundsException if there is no such element or * IllegalArgumentException if object is not an @@ -756,8 +923,6 @@ Map map = (Map) object; Iterator iterator = map.entrySet().iterator(); return get(iterator, index); - } else if (object instanceof List) { - return ((List) object).get(index); } else if (object instanceof Object[]) { return ((Object[]) object)[index]; } else if (object instanceof Iterator) { @@ -795,6 +960,20 @@ } } } + + /** + * Returns the index-th Map.Entry in the map's entrySet, throwing + * IndexOutOfBoundsException if there is no such element. + * + * @param map the object to get a value from + * @param index the index to get + * @return the object at the specified index + * @throws IndexOutOfBoundsException if the index is invalid + */ + public static Map.Entry get(Map map, int index) { + checkIndexBounds(index); + return get(map.entrySet(), index); + } /** * Gets the size of the collection/iterator specified. @@ -844,7 +1023,7 @@ } return total; } - + /** * Checks if the specified collection/array/iterator is empty. *

@@ -911,7 +1090,7 @@ * @since Commons Collections 3.2 */ public static boolean isNotEmpty(Collection coll) { - return !CollectionUtils.isEmpty(coll); + return !isEmpty(coll); } //----------------------------------------------------------------------- @@ -934,6 +1113,14 @@ } } + private static final int getFreq(final T obj, final Map freqMap) { + Integer count = freqMap.get(obj); + if (count != null) { + return count.intValue(); + } + return 0; + } + /** * Returns true if no more elements can be added to the Collection. *

@@ -959,7 +1146,7 @@ try { BoundedCollection bcoll = UnmodifiableBoundedCollection.decorateUsing(coll); return bcoll.isFull(); - + } catch (IllegalArgumentException ex) { return false; } @@ -990,7 +1177,7 @@ try { BoundedCollection bcoll = UnmodifiableBoundedCollection.decorateUsing(coll); return bcoll.maxSize(); - + } catch (IllegalArgumentException ex) { return -1; } @@ -1012,7 +1199,7 @@ * @throws NullPointerException if either parameter is null * @since Commons Collections 3.2 */ - public static Collection retainAll(Collection collection, Collection retain) { + public static Collection retainAll(Collection collection, Collection retain) { return ListUtils.retainAll(collection, retain); } @@ -1086,10 +1273,11 @@ * * @param collection the collection to predicate, must not be null * @param predicate the predicate for the collection, must not be null + * @param the type of objects in the Collection. * @return a predicated collection backed by the given collection * @throws IllegalArgumentException if the Collection is null */ - public static Collection predicatedCollection(Collection collection, Predicate predicate) { + public static Collection predicatedCollection(Collection collection, Predicate predicate) { return PredicatedCollection.decorate(collection, predicate); } Added: commons/proper/collections/branches/collections_jdk5_branch/src/test/org/apache/commons/collections/MockTestCase.java URL: http://svn.apache.org/viewvc/commons/proper/collections/branches/collections_jdk5_branch/src/test/org/apache/commons/collections/MockTestCase.java?rev=593144&view=auto ============================================================================== --- commons/proper/collections/branches/collections_jdk5_branch/src/test/org/apache/commons/collections/MockTestCase.java (added) +++ commons/proper/collections/branches/collections_jdk5_branch/src/test/org/apache/commons/collections/MockTestCase.java Thu Nov 8 04:21:55 2007 @@ -0,0 +1,68 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.ListIterator; + +import org.easymock.EasyMock; +import org.easymock.IExpectationSetters; + +/** + * Provides utilities for making mock-based tests. Most notable is the generic "type-safe" + * {@link #createMock(Class)} method, and {@link #replay()} and {@link #verify()} methods + * that call the respective methods on all created mock objects. + * + * @author Stephen Kestle + */ +public abstract class MockTestCase { + private List mockObjects = new ArrayList(); + + @SuppressWarnings("unchecked") + protected T createMock(Class name) { + T mock = (T) EasyMock.createMock(name); + return registerMock(mock); + } + + private T registerMock(T mock) { + mockObjects.add(mock); + return mock; + } + + protected IExpectationSetters expect(T t) { + return EasyMock.expect(t); + } + + protected final void replay() { + for (Iterator i = mockObjects.iterator(); i.hasNext();) { + EasyMock.replay(i.next()); + } + } + + protected final void verify() { + for (ListIterator i = mockObjects.listIterator(); i.hasNext();) { + try { + EasyMock.verify(i.next()); + } catch (AssertionError e) { + throw new AssertionError((i.previousIndex() + 1) + "" + + e.getMessage()); + } + } + } +}