diff --git a/src/main/java/org/apache/commons/collections4/CollectionUtils.java b/src/main/java/org/apache/commons/collections4/CollectionUtils.java index 1a12d9f79..11b0dcce4 100644 --- a/src/main/java/org/apache/commons/collections4/CollectionUtils.java +++ b/src/main/java/org/apache/commons/collections4/CollectionUtils.java @@ -614,29 +614,16 @@ public class CollectionUtils { * @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 + * @throws NullPointerException if coll is null + * @deprecated since 4.1, use {@link IterableUtils#cardinality(Iterable, Object)} instead. + * Be aware that the order of parameters has changed. */ + @Deprecated public static int cardinality(final O obj, final Iterable coll) { - if (coll instanceof Set) { - return ((Set) coll).contains(obj) ? 1 : 0; + if (coll == null) { + throw new NullPointerException("coll must not be null."); } - if (coll instanceof Bag) { - return ((Bag) coll).getCount(obj); - } - int count = 0; - if (obj == null) { - for (final Object element : coll) { - if (element == null) { - count++; - } - } - } else { - for (final Object element : coll) { - if (obj.equals(element)) { - count++; - } - } - } - return count; + return IterableUtils.cardinality(coll, obj); } /** @@ -820,11 +807,11 @@ public class CollectionUtils { * @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 - * @deprecated since 4.1, use {@link IterableUtils#frequency(Iterable, Predicate)} instead + * @deprecated since 4.1, use {@link IterableUtils#countMatches(Iterable, Predicate)} instead */ @Deprecated public static int countMatches(final Iterable input, final Predicate predicate) { - return predicate == null ? 0 : (int) IterableUtils.frequency(input, predicate); + return predicate == null ? 0 : (int) IterableUtils.countMatches(input, predicate); } /** diff --git a/src/main/java/org/apache/commons/collections4/IterableUtils.java b/src/main/java/org/apache/commons/collections4/IterableUtils.java index 9088bd4cb..f9f203b94 100644 --- a/src/main/java/org/apache/commons/collections4/IterableUtils.java +++ b/src/main/java/org/apache/commons/collections4/IterableUtils.java @@ -22,6 +22,7 @@ import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; +import java.util.Set; import org.apache.commons.collections4.functors.EqualPredicate; import org.apache.commons.collections4.iterators.LazyIteratorChain; @@ -238,14 +239,14 @@ public class IterableUtils { * * @param the element type * @param iterable the iterable to filter, may be null - * @param predicate the predicate used to filter elements, must not be null + * @param predicate the predicate used to filter elements, may not be null * @return a filtered view on the specified iterable * @throws NullPointerException if predicate is null */ public static Iterable filteredIterable(final Iterable iterable, final Predicate predicate) { if (predicate == null) { - throw new NullPointerException("predicate must not be null."); + throw new NullPointerException("Predicate must not be null."); } return new FluentIterable() { @@ -274,7 +275,7 @@ public class IterableUtils { */ public static Iterable boundedIterable(final Iterable iterable, final long maxSize) { if (maxSize < 0) { - throw new IllegalArgumentException("maxSize parameter must not be negative."); + throw new IllegalArgumentException("MaxSize parameter must not be negative."); } return new FluentIterable() { @@ -372,7 +373,7 @@ public class IterableUtils { */ public static Iterable skippingIterable(final Iterable iterable, final long elementsToSkip) { if (elementsToSkip < 0) { - throw new IllegalArgumentException("elementsToSkip parameter must not be negative."); + throw new IllegalArgumentException("ElementsToSkip parameter must not be negative."); } return new FluentIterable() { @@ -403,7 +404,7 @@ public class IterableUtils { public static Iterable transformedIterable(final Iterable iterable, final Transformer transformer) { if (transformer == null) { - throw new NullPointerException("transformer must not be null."); + throw new NullPointerException("Transformer must not be null."); } return new FluentIterable() { @@ -540,13 +541,13 @@ public class IterableUtils { /** * Returns an empty iterator if the argument is null, - * or returns {@code iterable.iterator()} otherwise. + * or {@code iterable.iterator()} otherwise. * * @param the element type * @param iterable the iterable, possibly null - * @return an empty collection if the argument is null + * @return an empty iterator if the argument is null */ - public static Iterator emptyIteratorIfNull(final Iterable iterable) { + private static Iterator emptyIteratorIfNull(final Iterable iterable) { return iterable != null ? iterable.iterator() : IteratorUtils.emptyIterator(); } @@ -635,19 +636,11 @@ public class IterableUtils { * @return the number of matches for the predicate in the collection * @throws NullPointerException if predicate is null */ - public static long frequency(final Iterable input, final Predicate predicate) { + public static long countMatches(final Iterable input, final Predicate predicate) { if (predicate == null) { throw new NullPointerException("Predicate must not be null."); } - long count = 0; - if (input != null) { - for (final E o : input) { - if (predicate.evaluate(o)) { - count++; - } - } - } - return count; + return size(filteredIterable(input, predicate)); } /** @@ -709,6 +702,24 @@ public class IterableUtils { return matchesAny(iterable, EqualPredicate.equalPredicate(object, equator)); } + /** + * Returns the number of occurrences of the provided object in the iterable. + * + * @param the type of object that the {@link Iterable} may contain + * @param iterable the {@link Iterable} to search + * @param obj the object to find the cardinality of + * @return the the number of occurrences of obj in iterable + */ + public static int cardinality(final Iterable iterable, final T obj) { + if (iterable instanceof Set) { + return ((Set) iterable).contains(obj) ? 1 : 0; + } + if (iterable instanceof Bag) { + return ((Bag) iterable).getCount(obj); + } + return size(filteredIterable(iterable, EqualPredicate.equalPredicate(obj))); + } + /** * Returns the index-th value in the iterable's {@link Iterator}, throwing * IndexOutOfBoundsException if there is no such element. diff --git a/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java b/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java index 8c9e8f49e..851b0dd19 100644 --- a/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java @@ -188,6 +188,7 @@ public class CollectionUtilsTest extends MockTestCase { } @Test + @Deprecated public void cardinality() { assertEquals(1, CollectionUtils.cardinality(1, iterableA)); assertEquals(2, CollectionUtils.cardinality(2, iterableA)); @@ -231,6 +232,7 @@ public class CollectionUtilsTest extends MockTestCase { } @Test + @Deprecated public void cardinalityOfNull() { final List list = new ArrayList(); assertEquals(0, CollectionUtils.cardinality(null, list)); @@ -671,6 +673,7 @@ public class CollectionUtilsTest extends MockTestCase { } @Test + @Deprecated public void forAllButLastDoCollection() { final Closure> testClosure = ClosureUtils.invokerClosure("clear"); final Collection> col = new ArrayList>(); diff --git a/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java b/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java index 3cdf421b3..7e3abbb9e 100644 --- a/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java +++ b/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java @@ -20,10 +20,13 @@ import static org.apache.commons.collections4.functors.EqualPredicate.*; import static org.junit.Assert.*; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; import java.util.LinkedList; import java.util.List; +import java.util.Set; import org.apache.commons.collections4.bag.HashBag; import org.junit.Assert; @@ -197,6 +200,72 @@ public class IterableUtilsTest { } // this is what we want } + @Test + public void cardinality() { + // null iterable test + assertEquals(0, IterableUtils.cardinality(null, 1)); + + assertEquals(1, IterableUtils.cardinality(iterableA, 1)); + assertEquals(2, IterableUtils.cardinality(iterableA, 2)); + assertEquals(3, IterableUtils.cardinality(iterableA, 3)); + assertEquals(4, IterableUtils.cardinality(iterableA, 4)); + assertEquals(0, IterableUtils.cardinality(iterableA, 5)); + + assertEquals(0, IterableUtils.cardinality(iterableB, 1L)); + assertEquals(4, IterableUtils.cardinality(iterableB, 2L)); + assertEquals(3, IterableUtils.cardinality(iterableB, 3L)); + assertEquals(2, IterableUtils.cardinality(iterableB, 4L)); + assertEquals(1, IterableUtils.cardinality(iterableB, 5L)); + + // Ensure that generic bounds accept valid parameters, but return + // expected results + // e.g. no longs in the "int" Iterable, and vice versa. + Iterable iterableIntAsNumber = Arrays.asList(1, 2, 3, 4, 5); + Iterable iterableLongAsNumber = Arrays.asList(1L, 2L, 3L, 4L, 5L); + assertEquals(0, IterableUtils.cardinality(iterableIntAsNumber, 2L)); + assertEquals(0, IterableUtils.cardinality(iterableLongAsNumber, 2)); + + final Set set = new HashSet(); + set.add("A"); + set.add("C"); + set.add("E"); + set.add("E"); + assertEquals(1, IterableUtils.cardinality(set, "A")); + assertEquals(0, IterableUtils.cardinality(set, "B")); + assertEquals(1, IterableUtils.cardinality(set, "C")); + assertEquals(0, IterableUtils.cardinality(set, "D")); + assertEquals(1, IterableUtils.cardinality(set, "E")); + + final Bag bag = new HashBag(); + bag.add("A", 3); + bag.add("C"); + bag.add("E"); + bag.add("E"); + assertEquals(3, IterableUtils.cardinality(bag, "A")); + assertEquals(0, IterableUtils.cardinality(bag, "B")); + assertEquals(1, IterableUtils.cardinality(bag, "C")); + assertEquals(0, IterableUtils.cardinality(bag, "D")); + assertEquals(2, IterableUtils.cardinality(bag, "E")); + } + + @Test + public void cardinalityOfNull() { + final List list = new ArrayList(); + assertEquals(0, IterableUtils.cardinality(list, null)); + list.add("A"); + assertEquals(0, IterableUtils.cardinality(list, null)); + list.add(null); + assertEquals(1, IterableUtils.cardinality(list, null)); + list.add("B"); + assertEquals(1, IterableUtils.cardinality(list, null)); + list.add(null); + assertEquals(2, IterableUtils.cardinality(list, null)); + list.add("B"); + assertEquals(2, IterableUtils.cardinality(list, null)); + list.add(null); + assertEquals(3, IterableUtils.cardinality(list, null)); + } + @Test public void find() { Predicate testPredicate = equalPredicate((Number) 4); @@ -215,19 +284,19 @@ public class IterableUtilsTest { } @Test - public void frequency() { - assertEquals(4, IterableUtils.frequency(iterableB, EQUALS_TWO)); - assertEquals(0, IterableUtils.frequency(null, EQUALS_TWO)); + public void countMatches() { + assertEquals(4, IterableUtils.countMatches(iterableB, EQUALS_TWO)); + assertEquals(0, IterableUtils.countMatches(null, EQUALS_TWO)); try { - assertEquals(0, IterableUtils.frequency(iterableA, null)); + assertEquals(0, IterableUtils.countMatches(iterableA, null)); fail("predicate must not be null"); } catch (NullPointerException ex) { // expected } try { - assertEquals(0, IterableUtils.frequency(null, null)); + assertEquals(0, IterableUtils.countMatches(null, null)); fail("predicate must not be null"); } catch (NullPointerException ex) { // expected