Author: tn Date: Sat Jun 6 08:54:54 2015 New Revision: 1683894 URL: http://svn.apache.org/viewvc?rev=1683894&view=rev Log: [COLLECTIONS-551] Move partition methods from CollectionUtils to IterableUtils. Make method consistent: do not allow null predicates, return the same for a null iterable as for an empty one.
Modified: commons/proper/collections/trunk/src/changes/changes.xml commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/CollectionUtils.java commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/IterableUtils.java commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java Modified: commons/proper/collections/trunk/src/changes/changes.xml URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/changes/changes.xml?rev=1683894&r1=1683893&r2=1683894&view=diff ============================================================================== --- commons/proper/collections/trunk/src/changes/changes.xml (original) +++ commons/proper/collections/trunk/src/changes/changes.xml Sat Jun 6 08:54:54 2015 @@ -98,7 +98,7 @@ that are prefixed by the given search key in some rare cases. </action> <action issue="COLLECTIONS-511" dev="tn" type="add" due-to="Nathan Blomquist, Brent Worden"> - Added new methods "CollectionUtils#partition(...)" to partition an input collection + Added new methods "IterableUtils#partition(...)" to partition an input collection into separate output collections based on evaluation of one or more predicates. </action> <action issue="COLLECTIONS-537" dev="tn" type="fix" due-to="Frank Jakop"> Modified: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/CollectionUtils.java URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/CollectionUtils.java?rev=1683894&r1=1683893&r2=1683894&view=diff ============================================================================== --- commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/CollectionUtils.java (original) +++ commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/CollectionUtils.java Sat Jun 6 08:54:54 2015 @@ -19,7 +19,6 @@ package org.apache.commons.collections4; import java.lang.reflect.Array; import java.util.ArrayList; import java.util.Collection; -import java.util.Collections; import java.util.Comparator; import java.util.Enumeration; import java.util.HashMap; @@ -919,93 +918,7 @@ public class CollectionUtils { } /** - * Selects all elements from inputCollection which don't match the given - * predicate into an output collection. - * <p> - * If the input predicate is <code>null</code>, the result is an empty - * list. - * - * @param <O> the type of object the {@link Iterable} contains - * @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 <b>not</b> matching the predicate (new list) - * @throws NullPointerException if the input collection is null - */ - public static <O> Collection<O> selectRejected(final Iterable<? extends O> inputCollection, - final Predicate<? super O> predicate) { - final Collection<O> answer = inputCollection instanceof Collection<?> ? - new ArrayList<O>(((Collection<?>) inputCollection).size()) : new ArrayList<O>(); - return selectRejected(inputCollection, predicate, answer); - } - - /** - * Selects all elements from inputCollection which don't match the given - * predicate and adds them to outputCollection. - * <p> - * If the input predicate is <code>null</code>, no elements are added to - * <code>outputCollection</code>. - * - * @param <O> the type of object the {@link Iterable} contains - * @param <R> the type of the output {@link 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 if the inputCollection - * and predicate or not null - * @return outputCollection - */ - public static <O, R extends Collection<? super O>> R selectRejected(final Iterable<? extends O> inputCollection, - final Predicate<? super O> predicate, final R outputCollection) { - - if (inputCollection != null && predicate != null) { - for (final O item : inputCollection) { - if (!predicate.evaluate(item)) { - outputCollection.add(item); - } - } - } - return outputCollection; - } - - /** - * Partitions all elements from inputCollection into separate output collections, - * based on the evaluation of the given predicate. - * <p> - * For each predicate, the result will contain a list holding all elements of the - * input collection matching the predicate. The last list will hold all elements - * which didn't match any predicate: - * <pre> - * [C1, R] = partition(I, P1) with - * I = input collection - * P1 = first predicate - * C1 = collection of elements matching P1 - * R = collection of elements rejected by all predicates - * </pre> - * <p> - * If the input collection is <code>null</code>, an empty list will be returned. - * If the input predicate is <code>null</code>, all elements of the input collection - * will be added to the rejected collection. - * <p> - * Example: for an input list [1, 2, 3, 4, 5] calling partition with a predicate [x < 3] - * will result in the following output: [[1, 2], [3, 4, 5]]. - * - * @param <O> the type of object the {@link Iterable} contains - * @param inputCollection the collection to get the input from, may be null - * @param predicate the predicate to use, may be null - * @return a list containing the output collections - * @since 4.1 - */ - public static <O> List<List<O>> partition(final Iterable<? extends O> inputCollection, - final Predicate<? super O> predicate) { - - @SuppressWarnings({ "unchecked", "rawtypes" }) // safe - final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class); - @SuppressWarnings("unchecked") // safe - final Predicate<? super O>[] predicates = new Predicate[] { predicate }; - return partition(inputCollection, factory, predicates); - } - - /** - * Partitions all elements from inputCollection into an output and rejected collection, + * Selects all elements from inputCollection into an output and rejected collection, * based on the evaluation of the given predicate. * <p> * Elements matching the predicate are added to the <code>outputCollection</code>, @@ -1028,9 +941,10 @@ public class CollectionUtils { * inputCollection and predicate are not null * @param rejectedCollection the collection to output rejected elements into, may not be null if the * inputCollection or predicate are not null + * @return the outputCollection * @since 4.1 */ - public static <O, R extends Collection<? super O>> void partition(final Iterable<? extends O> inputCollection, + public static <O, R extends Collection<? super O>> R select(final Iterable<? extends O> inputCollection, final Predicate<? super O> predicate, R outputCollection, R rejectedCollection) { if (inputCollection != null && predicate != null) { @@ -1042,128 +956,55 @@ public class CollectionUtils { } } } + return outputCollection; } /** - * Partitions all elements from inputCollection into separate output collections, - * based on the evaluation of the given predicates. - * <p> - * For each predicate, the result will contain a list holding all elements of the - * input collection matching the predicate. The last list will hold all elements - * which didn't match any predicate: - * <pre> - * [C1, C2, R] = partition(I, P1, P2) with - * I = input collection - * P1 = first predicate - * P2 = second predicate - * C1 = collection of elements matching P1 - * C2 = collection of elements matching P2 - * R = collection of elements rejected by all predicates - * </pre> - * <p> - * <b>Note</b>: elements are only added to the output collection of the first matching - * predicate, determined by the order of arguments. - * <p> - * If the input collection is <code>null</code>, an empty list will be returned. - * If the input predicate is <code>null</code>, all elements of the input collection - * will be added to the rejected collection. + * Selects all elements from inputCollection which don't match the given + * predicate into an output collection. * <p> - * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x < 3] - * and [x < 5] will result in the following output: [[1, 2], [3, 4], [5]]. + * If the input predicate is <code>null</code>, the result is an empty + * list. * * @param <O> the type of object the {@link Iterable} contains - * @param inputCollection the collection to get the input from, may be null - * @param predicates the predicates to use, may be null - * @return a list containing the output collections - * @since 4.1 + * @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 <b>not</b> matching the predicate (new list) + * @throws NullPointerException if the input collection is null */ - public static <O> List<List<O>> partition(final Iterable<? extends O> inputCollection, - final Predicate<? super O>... predicates) { - - @SuppressWarnings({ "unchecked", "rawtypes" }) // safe - final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class); - return partition(inputCollection, factory, predicates); + public static <O> Collection<O> selectRejected(final Iterable<? extends O> inputCollection, + final Predicate<? super O> predicate) { + final Collection<O> answer = inputCollection instanceof Collection<?> ? + new ArrayList<O>(((Collection<?>) inputCollection).size()) : new ArrayList<O>(); + return selectRejected(inputCollection, predicate, answer); } /** - * Partitions all elements from inputCollection into separate output collections, - * based on the evaluation of the given predicates. - * <p> - * For each predicate, the returned list will contain a collection holding - * all elements of the input collection matching the predicate. The last collection - * contained in the list will hold all elements which didn't match any predicate: - * <pre> - * [C1, C2, R] = partition(I, P1, P2) with - * I = input collection - * P1 = first predicate - * P2 = second predicate - * C1 = collection of elements matching P1 - * C2 = collection of elements matching P2 - * R = collection of elements rejected by all predicates - * </pre> - * <p> - * <b>Note</b>: elements are only added to the output collection of the first matching - * predicate, determined by the order of arguments. - * <p> - * If the input collection is <code>null</code>, an empty list will be returned. - * If no predicates have been provided, all elements of the input collection - * will be added to the rejected collection. + * Selects all elements from inputCollection which don't match the given + * predicate and adds them to outputCollection. * <p> - * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x < 3] - * and [x < 5] will result in the following output: [[1, 2], [3, 4], [5]]. + * If the input predicate is <code>null</code>, no elements are added to + * <code>outputCollection</code>. * * @param <O> the type of object the {@link Iterable} contains * @param <R> the type of the output {@link Collection} * @param inputCollection the collection to get the input from, may be null - * @param partitionFactory the factory used to create the output collections - * @param predicates the predicates to use, may be empty - * @return a list containing the output collections - * @since 4.1 + * @param predicate the predicate to use, may be null + * @param outputCollection the collection to output into, may not be null if the inputCollection + * and predicate or not null + * @return outputCollection */ - public static <O, R extends Collection<O>> List<R> partition(final Iterable<? extends O> inputCollection, - final Factory<R> partitionFactory, final Predicate<? super O>... predicates) { - - if (inputCollection == null) { - return Collections.emptyList(); - } + public static <O, R extends Collection<? super O>> R selectRejected(final Iterable<? extends O> inputCollection, + final Predicate<? super O> predicate, final R outputCollection) { - if (predicates == null || predicates.length < 1) { - // return the entire input collection as a single partition - final R singlePartition = partitionFactory.create(); - select(inputCollection, PredicateUtils.truePredicate(), singlePartition); - return Collections.singletonList(singlePartition); - } - - // create the empty partitions - final int numberOfPredicates = predicates.length; - final int numberOfPartitions = numberOfPredicates + 1; - final List<R> partitions = new ArrayList<R>(numberOfPartitions); - for (int i = 0; i < numberOfPartitions; ++i) { - partitions.add(partitionFactory.create()); - } - - // for each element in inputCollection: - // find the first predicate that evaluates to true. - // if there is a predicate, add the element to the corresponding partition. - // if there is no predicate, add it to the last, catch-all partition. - for (final O element : inputCollection) { - boolean elementAssigned = false; - for (int i = 0; i < numberOfPredicates; ++i) { - if (predicates[i].evaluate(element)) { - partitions.get(i).add(element); - elementAssigned = true; - break; + if (inputCollection != null && predicate != null) { + for (final O item : inputCollection) { + if (!predicate.evaluate(item)) { + outputCollection.add(item); } } - - if (!elementAssigned) { - // no predicates evaluated to true - // add element to last partition - partitions.get(numberOfPredicates).add(element); - } } - - return partitions; + return outputCollection; } /** Modified: commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/IterableUtils.java URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/IterableUtils.java?rev=1683894&r1=1683893&r2=1683894&view=diff ============================================================================== --- commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/IterableUtils.java (original) +++ commons/proper/collections/trunk/src/main/java/org/apache/commons/collections4/IterableUtils.java Sat Jun 6 08:54:54 2015 @@ -16,7 +16,9 @@ */ package org.apache.commons.collections4; +import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.Iterator; import java.util.List; @@ -681,6 +683,178 @@ public class IterableUtils { } /** + * Partitions all elements from iterable into separate output collections, + * based on the evaluation of the given predicate. + * <p> + * For each predicate, the result will contain a list holding all elements of the + * input iterable matching the predicate. The last list will hold all elements + * which didn't match any predicate: + * <pre> + * [C1, R] = partition(I, P1) with + * I = input + * P1 = first predicate + * C1 = collection of elements matching P1 + * R = collection of elements rejected by all predicates + * </pre> + * <p> + * If the input iterable is <code>null</code>, the same is returned as for an + * empty iterable. + * <p> + * Example: for an input list [1, 2, 3, 4, 5] calling partition with a predicate [x < 3] + * will result in the following output: [[1, 2], [3, 4, 5]]. + * + * @param <O> the type of object the {@link Iterable} contains + * @param iterable the iterable to partition, may be null + * @param predicate the predicate to use, may not be null + * @return a list containing the output collections + * @throws NullPointerException if predicate is null + */ + public static <O> List<List<O>> partition(final Iterable<? extends O> iterable, + final Predicate<? super O> predicate) { + if (predicate == null) { + throw new NullPointerException("Predicate must not be null."); + } + @SuppressWarnings({ "unchecked", "rawtypes" }) // safe + final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class); + @SuppressWarnings("unchecked") // safe + final Predicate<? super O>[] predicates = new Predicate[] { predicate }; + return partition(iterable, factory, predicates); + } + + /** + * Partitions all elements from iterable into separate output collections, + * based on the evaluation of the given predicates. + * <p> + * For each predicate, the result will contain a list holding all elements of the + * input iterable matching the predicate. The last list will hold all elements + * which didn't match any predicate: + * <pre> + * [C1, C2, R] = partition(I, P1, P2) with + * I = input + * P1 = first predicate + * P2 = second predicate + * C1 = collection of elements matching P1 + * C2 = collection of elements matching P2 + * R = collection of elements rejected by all predicates + * </pre> + * <p> + * <b>Note</b>: elements are only added to the output collection of the first matching + * predicate, determined by the order of arguments. + * <p> + * If the input iterable is <code>null</code>, the same is returned as for an + * empty iterable. + * <p> + * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x < 3] + * and [x < 5] will result in the following output: [[1, 2], [3, 4], [5]]. + * + * @param <O> the type of object the {@link Iterable} contains + * @param iterable the collection to get the input from, may be null + * @param predicates the predicates to use, may not be null + * @return a list containing the output collections + * @throws NullPointerException if any predicate is null + */ + public static <O> List<List<O>> partition(final Iterable<? extends O> iterable, + final Predicate<? super O>... predicates) { + + @SuppressWarnings({ "unchecked", "rawtypes" }) // safe + final Factory<List<O>> factory = FactoryUtils.instantiateFactory((Class) ArrayList.class); + return partition(iterable, factory, predicates); + } + + /** + * Partitions all elements from iterable into separate output collections, + * based on the evaluation of the given predicates. + * <p> + * For each predicate, the returned list will contain a collection holding + * all elements of the input iterable matching the predicate. The last collection + * contained in the list will hold all elements which didn't match any predicate: + * <pre> + * [C1, C2, R] = partition(I, P1, P2) with + * I = input + * P1 = first predicate + * P2 = second predicate + * C1 = collection of elements matching P1 + * C2 = collection of elements matching P2 + * R = collection of elements rejected by all predicates + * </pre> + * <p> + * <b>Note</b>: elements are only added to the output collection of the first matching + * predicate, determined by the order of arguments. + * <p> + * If the input iterable is <code>null</code>, the same is returned as for an + * empty iterable. + * If no predicates have been provided, all elements of the input collection + * will be added to the rejected collection. + * <p> + * Example: for an input list [1, 2, 3, 4, 5] calling partition with predicates [x < 3] + * and [x < 5] will result in the following output: [[1, 2], [3, 4], [5]]. + * + * @param <O> the type of object the {@link Iterable} contains + * @param <R> the type of the output {@link Collection} + * @param iterable the collection to get the input from, may be null + * @param partitionFactory the factory used to create the output collections + * @param predicates the predicates to use, may not be null + * @return a list containing the output collections + * @throws NullPointerException if any predicate is null + */ + public static <O, R extends Collection<O>> List<R> partition(final Iterable<? extends O> iterable, + final Factory<R> partitionFactory, final Predicate<? super O>... predicates) { + + if (iterable == null) { + final Iterable<O> empty = emptyIterable(); + return partition(empty, partitionFactory, predicates); + } + + if (predicates == null) { + throw new NullPointerException("Predicates must not be null."); + } + + for (Predicate<?> p : predicates) { + if (p == null) { + throw new NullPointerException("Predicate must not be null."); + } + } + + if (predicates.length < 1) { + // return the entire input collection as a single partition + final R singlePartition = partitionFactory.create(); + CollectionUtils.addAll(singlePartition, iterable); + return Collections.singletonList(singlePartition); + } + + // create the empty partitions + final int numberOfPredicates = predicates.length; + final int numberOfPartitions = numberOfPredicates + 1; + final List<R> partitions = new ArrayList<R>(numberOfPartitions); + for (int i = 0; i < numberOfPartitions; ++i) { + partitions.add(partitionFactory.create()); + } + + // for each element in inputCollection: + // find the first predicate that evaluates to true. + // if there is a predicate, add the element to the corresponding partition. + // if there is no predicate, add it to the last, catch-all partition. + for (final O element : iterable) { + boolean elementAssigned = false; + for (int i = 0; i < numberOfPredicates; ++i) { + if (predicates[i].evaluate(element)) { + partitions.get(i).add(element); + elementAssigned = true; + break; + } + } + + if (!elementAssigned) { + // no predicates evaluated to true + // add element to last partition + partitions.get(numberOfPredicates).add(element); + } + } + + return partitions; + } + + /** * Gets a new list with the contents of the provided iterable. * * @param <E> the element type Modified: commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java?rev=1683894&r1=1683893&r2=1683894&view=diff ============================================================================== --- commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java (original) +++ commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/CollectionUtilsTest.java Sat Jun 6 08:54:54 2015 @@ -1070,12 +1070,6 @@ public class CollectionUtilsTest extends } }; - private static Predicate<Number> EVEN = new Predicate<Number>() { - public boolean evaluate(final Number input) { - return input.intValue() % 2 == 0; - } - }; - //Up to here @Test public void filter() { @@ -1171,55 +1165,7 @@ public class CollectionUtilsTest extends } @Test - public void selectRejected() { - final List<Long> list = new ArrayList<Long>(); - list.add(1L); - list.add(2L); - list.add(3L); - list.add(4L); - final Collection<Long> output1 = CollectionUtils.selectRejected(list, EQUALS_TWO); - final Collection<? extends Number> output2 = CollectionUtils.selectRejected(list, EQUALS_TWO); - final HashSet<Number> output3 = CollectionUtils.selectRejected(list, EQUALS_TWO, new HashSet<Number>()); - assertTrue(CollectionUtils.isEqualCollection(output1, output2)); - assertTrue(CollectionUtils.isEqualCollection(output1, output3)); - assertEquals(4, list.size()); - assertEquals(3, output1.size()); - assertTrue(output1.contains(1L)); - assertTrue(output1.contains(3L)); - assertTrue(output1.contains(4L)); - } - - @SuppressWarnings("unchecked") - @Test - public void partition() { - List<Integer> input = new ArrayList<Integer>(); - input.add(1); - input.add(2); - input.add(3); - input.add(4); - List<List<Integer>> partitions = CollectionUtils.partition(input, EQUALS_TWO); - assertEquals(2, partitions.size()); - - // first partition contains 2 - Collection<Integer> partition = partitions.get(0); - assertEquals(1, partition.size()); - assertEquals(2, CollectionUtils.extractSingleton(partition).intValue()); - - // second partition contains 1, 3, and 4 - Integer[] expected = {1, 3, 4}; - partition = partitions.get(1); - Assert.assertArrayEquals(expected, partition.toArray()); - - partitions = CollectionUtils.partition((List<Integer>) null, EQUALS_TWO); - assertTrue(partitions.isEmpty()); - - partitions = CollectionUtils.partition(input); - assertEquals(1, partitions.size()); - assertEquals(input, partitions.get(0)); - } - - @Test - public void partitionWithOutputCollections() { + public void selectWithOutputCollections() { List<Integer> input = new ArrayList<Integer>(); input.add(1); input.add(2); @@ -1229,7 +1175,7 @@ public class CollectionUtilsTest extends List<Integer> output = new ArrayList<Integer>(); List<Integer> rejected = new ArrayList<Integer>(); - CollectionUtils.partition(input, EQUALS_TWO, output, rejected); + CollectionUtils.select(input, EQUALS_TWO, output, rejected); // output contains 2 assertEquals(1, output.size()); @@ -1241,37 +1187,30 @@ public class CollectionUtilsTest extends output.clear(); rejected.clear(); - CollectionUtils.partition((List<Integer>) null, EQUALS_TWO, output, rejected); + CollectionUtils.select((List<Integer>) null, EQUALS_TWO, output, rejected); assertTrue(output.isEmpty()); assertTrue(rejected.isEmpty()); } @Test - public void partitionMultiplePredicates() { - List<Integer> input = new ArrayList<Integer>(); - input.add(1); - input.add(2); - input.add(3); - input.add(4); - @SuppressWarnings("unchecked") - List<List<Integer>> partitions = CollectionUtils.partition(input, EQUALS_TWO, EVEN); - - // first partition contains 2 - Collection<Integer> partition = partitions.get(0); - assertEquals(1, partition.size()); - assertEquals(2, partition.iterator().next().intValue()); - - // second partition contains 4 - partition = partitions.get(1); - assertEquals(1, partition.size()); - assertEquals(4, partition.iterator().next().intValue()); - - // third partition contains 1 and 3 - Integer[] expected = {1, 3}; - partition = partitions.get(2); - Assert.assertArrayEquals(expected, partition.toArray()); + public void selectRejected() { + final List<Long> list = new ArrayList<Long>(); + list.add(1L); + list.add(2L); + list.add(3L); + list.add(4L); + final Collection<Long> output1 = CollectionUtils.selectRejected(list, EQUALS_TWO); + final Collection<? extends Number> output2 = CollectionUtils.selectRejected(list, EQUALS_TWO); + final HashSet<Number> output3 = CollectionUtils.selectRejected(list, EQUALS_TWO, new HashSet<Number>()); + assertTrue(CollectionUtils.isEqualCollection(output1, output2)); + assertTrue(CollectionUtils.isEqualCollection(output1, output3)); + assertEquals(4, list.size()); + assertEquals(3, output1.size()); + assertTrue(output1.contains(1L)); + assertTrue(output1.contains(3L)); + assertTrue(output1.contains(4L)); } - + @Test public void collect() { final Transformer<Number, Long> transformer = TransformerUtils.constantTransformer(2L); Modified: commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java URL: http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java?rev=1683894&r1=1683893&r2=1683894&view=diff ============================================================================== --- commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java (original) +++ commons/proper/collections/trunk/src/test/java/org/apache/commons/collections4/IterableUtilsTest.java Sat Jun 6 08:54:54 2015 @@ -26,6 +26,7 @@ import java.util.LinkedList; import java.util.List; import org.apache.commons.collections4.bag.HashBag; +import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -89,6 +90,12 @@ public class IterableUtilsTest { } }; + private static Predicate<Number> EVEN = new Predicate<Number>() { + public boolean evaluate(final Number input) { + return input.intValue() % 2 == 0; + } + }; + // ----------------------------------------------------------------------- @Test public void apply() { @@ -269,6 +276,76 @@ public class IterableUtilsTest { IterableUtils.get(bag, 1); } + @SuppressWarnings("unchecked") + @Test + public void partition() { + List<Integer> input = new ArrayList<Integer>(); + input.add(1); + input.add(2); + input.add(3); + input.add(4); + List<List<Integer>> partitions = IterableUtils.partition(input, EQUALS_TWO); + assertEquals(2, partitions.size()); + + // first partition contains 2 + Collection<Integer> partition = partitions.get(0); + assertEquals(1, partition.size()); + assertEquals(2, CollectionUtils.extractSingleton(partition).intValue()); + + // second partition contains 1, 3, and 4 + Integer[] expected = {1, 3, 4}; + partition = partitions.get(1); + Assert.assertArrayEquals(expected, partition.toArray()); + + partitions = IterableUtils.partition((List<Integer>) null, EQUALS_TWO); + assertEquals(2, partitions.size()); + assertTrue(partitions.get(0).isEmpty()); + assertTrue(partitions.get(1).isEmpty()); + + partitions = IterableUtils.partition(input); + assertEquals(1, partitions.size()); + assertEquals(input, partitions.get(0)); + + try { + IterableUtils.partition(input, (Predicate<Integer>) null); + fail("expecting NullPointerException"); + } catch (NullPointerException npe) { + // expected + } + } + + @SuppressWarnings("unchecked") + @Test + public void partitionMultiplePredicates() { + List<Integer> input = new ArrayList<Integer>(); + input.add(1); + input.add(2); + input.add(3); + input.add(4); + List<List<Integer>> partitions = IterableUtils.partition(input, EQUALS_TWO, EVEN); + + // first partition contains 2 + Collection<Integer> partition = partitions.get(0); + assertEquals(1, partition.size()); + assertEquals(2, partition.iterator().next().intValue()); + + // second partition contains 4 + partition = partitions.get(1); + assertEquals(1, partition.size()); + assertEquals(4, partition.iterator().next().intValue()); + + // third partition contains 1 and 3 + Integer[] expected = {1, 3}; + partition = partitions.get(2); + Assert.assertArrayEquals(expected, partition.toArray()); + + try { + IterableUtils.partition(input, EQUALS_TWO, null); + } catch (NullPointerException npe) { + // expected + } + } + @Test public void testToString() { String result = IterableUtils.toString(iterableA);