You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by tn...@apache.org on 2013/04/25 22:02:15 UTC

svn commit: r1475937 - in /commons/proper/collections/trunk/src: changes/changes.xml main/java/org/apache/commons/collections4/CollectionUtils.java test/java/org/apache/commons/collections4/CollectionUtilsTest.java

Author: tn
Date: Thu Apr 25 20:02:15 2013
New Revision: 1475937

URL: http://svn.apache.org/r1475937
Log:
[COLLECTIONS-450] Added CollectionUtils.forAllButLastDo(...) methods. Thanks to J. Moldawski

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/test/java/org/apache/commons/collections4/CollectionUtilsTest.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=1475937&r1=1475936&r2=1475937&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/changes/changes.xml (original)
+++ commons/proper/collections/trunk/src/changes/changes.xml Thu Apr 25 20:02:15 2013
@@ -28,6 +28,10 @@
     <action issue="COLLECTIONS-451" dev="tn" type="update">
       The constructors for all Utils classes are now private to prevent instantiation.
     </action>
+    <action issue="COLLECTIONS-450" dev="tn" type="add" due-to="J. Moldawski">
+      Added methods "forAllButLastDo(Collection, Closure)" and "forAllButLastDo(Iterator, Closure)"
+      to class "CollectionUtils".
+    </action>
     <action issue="COLLECTIONS-447" dev="tn" type="fix" due-to="Jeffrey Barnes">
       Tree traversal with a TreeListIterator will not be affected anymore by
       the removal of an element directly after a call to previous().

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=1475937&r1=1475936&r2=1475937&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 Thu Apr 25 20:02:15 2013
@@ -695,6 +695,47 @@ public class CollectionUtils {
     }
 
     /**
+     * Executes the given closure on each but the last element in the collection.
+     * <p>
+     * If the input collection or closure is null, there is no change made.
+     *
+     * @param <T>  the type of object the {@link Collection} contains
+     * @param <C>  the closure type
+     * @param collection  the collection to get the input from, may be null
+     * @param closure  the closure to perform, may be null
+     * @return the last element in the collection, or null if either collection or closure is null
+     */
+    public static <T, C extends Closure<? super T>> T forAllButLastDo(final Collection<T> collection,
+                                                                      final C closure) {
+        return collection != null && closure != null ? forAllButLastDo(collection.iterator(), closure) : null;
+    }
+
+    /**
+     * Executes the given closure on each but the last element in the collection.
+     * <p>
+     * If the input collection or closure is null, there is no change made.
+     *
+     * @param <T>  the type of object the {@link Collection} contains
+     * @param <C>  the closure type
+     * @param iterator  the iterator to get the input from, may be null
+     * @param closure  the closure to perform, may be null
+     * @return the last element in the collection, or null if either iterator or closure is null
+     */
+    public static <T, C extends Closure<? super T>> T forAllButLastDo(final Iterator<T> iterator, final C closure) {
+        if (iterator != null && closure != null) {
+            while (iterator.hasNext()) {
+                final T element = iterator.next();
+                if (iterator.hasNext()) {
+                    closure.execute(element);
+                } else {
+                    return element;
+                }
+            }
+        }
+        return null;
+    }
+
+    /**
      * Filter the collection by applying a Predicate to each element. If the
      * predicate returns false, remove the element.
      * <p>

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=1475937&r1=1475936&r2=1475937&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 Thu Apr 25 20:02:15 2013
@@ -664,6 +664,61 @@ public class CollectionUtilsTest extends
     }
 
     @Test
+    public void forAllButLastDoCollection() {
+        final Closure<List<? extends Number>> testClosure = ClosureUtils.invokerClosure("clear");
+        final Collection<List<? extends Number>> col = new ArrayList<List<? extends Number>>();
+        col.add(collectionA);
+        col.add(collectionB);
+        List<? extends Number> lastElement = CollectionUtils.forAllButLastDo(col, testClosure);
+        assertSame(lastElement, collectionB);
+        assertTrue(collectionA.isEmpty() && !collectionB.isEmpty());
+
+        col.clear();
+        col.add(collectionB);
+        lastElement = CollectionUtils.forAllButLastDo(col, testClosure);
+        assertSame(lastElement, collectionB);
+        assertTrue(!collectionB.isEmpty() );
+
+        col.clear();
+        lastElement = CollectionUtils.forAllButLastDo(col, testClosure);
+        assertNull(lastElement);
+
+        Collection<String> strings = Arrays.asList(new String[]{"a", "b", "c"});
+        final StringBuffer result = new StringBuffer();
+        result.append(CollectionUtils.forAllButLastDo(strings, new Closure<String>() {
+            public void execute(String input) {
+                result.append(input+";");
+            }
+        }));
+        assertEquals("a;b;c", result.toString());
+
+        Collection<String> oneString = Arrays.asList(new String[]{"a"});
+        final StringBuffer resultOne = new StringBuffer();
+        resultOne.append(CollectionUtils.forAllButLastDo(oneString, new Closure<String>() {
+            public void execute(String input) {
+                resultOne.append(input+";");
+            }
+        }));
+        assertEquals("a", resultOne.toString());
+        assertNull(CollectionUtils.forAllButLastDo(strings, null));
+        assertNull(CollectionUtils.forAllButLastDo((Collection<?>) null, null));
+    }
+
+    @Test
+    public void forAllButLastDoIterator() {
+        final Closure<List<? extends Number>> testClosure = ClosureUtils.invokerClosure("clear");
+        final Collection<List<? extends Number>> col = new ArrayList<List<? extends Number>>();
+        col.add(collectionA);
+        col.add(collectionB);
+        List<? extends Number> lastElement = CollectionUtils.forAllButLastDo(col.iterator(), testClosure);
+        assertSame(lastElement, collectionB);
+        assertTrue(collectionA.isEmpty() && !collectionB.isEmpty());
+        
+        assertNull(CollectionUtils.forAllButLastDo(col.iterator(), null));
+        assertNull(CollectionUtils.forAllButLastDo((Collection<?>) null, null));
+    }
+    
+    @Test
     public void getFromMap() {
         // Unordered map, entries exist
         final Map<String, String> expected = new HashMap<String, String>();