Author: tn
Date: Thu Aug 16 20:50:27 2012
New Revision: 1374049

URL: http://svn.apache.org/viewvc?rev=1374049&view=rev
Log:
[COLLECTIONS-393] Added ListUtils.partition method, thanks to Chris Shayan for 
report and patch.

Modified:
    commons/proper/collections/trunk/src/changes/changes.xml
    
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/ListUtils.java
    
commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/TestListUtils.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=1374049&r1=1374048&r2=1374049&view=diff
==============================================================================
--- commons/proper/collections/trunk/src/changes/changes.xml (original)
+++ commons/proper/collections/trunk/src/changes/changes.xml Thu Aug 16 
20:50:27 2012
@@ -22,6 +22,9 @@
   <body>
 
   <release version="4.0" date="TBA" description="Next release">
+    <action issue="COLLECTIONS-393" dev="tn" type="add" due-to="Chris Shayan">
+      Added "ListUtils#partition" method to split a List into consecutive 
sublists.
+    </action>
     <action issue="COLLECTIONS-272" dev="tn" type="add" due-to="Chaitanya 
Mutyala">
       Added serialization support for "FixedOrderComparator" and 
"TransformingComparator".
     </action>

Modified: 
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/ListUtils.java
URL: 
http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/ListUtils.java?rev=1374049&r1=1374048&r2=1374049&view=diff
==============================================================================
--- 
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/ListUtils.java
 (original)
+++ 
commons/proper/collections/trunk/src/main/java/org/apache/commons/collections/ListUtils.java
 Thu Aug 16 20:50:27 2012
@@ -16,6 +16,7 @@
  */
 package org.apache.commons.collections;
 
+import java.util.AbstractList;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
@@ -438,5 +439,73 @@ public class ListUtils {
         }
         return -1;
     }
+
+    /**
+     * Returns consecutive {@link List#subList(int, int) sublists} of a
+     * list, each of the same size (the final list may be smaller). For 
example,
+     * partitioning a list containing {@code [a, b, c, d, e]} with a partition
+     * size of 3 yields {@code [[a, b, c], [d, e]]} -- an outer list containing
+     * two inner lists of three and two elements, all in the original order.
+     * <p>
+     * The outer list is unmodifiable, but reflects the latest state of the
+     * source list. The inner lists are sublist views of the original list,
+     * produced on demand using {@link List#subList(int, int)}, and are subject
+     * to all the usual caveats about modification as explained in that API.
+     * <p>
+     * Adapted from http://code.google.com/p/guava-libraries/
+     * 
+     * @param <T>  the element type
+     * @param list  the list to return consecutive sublists of
+     * @param size  the desired size of each sublist (the last may be smaller)
+     * @return a list of consecutive sublists
+     * @throws IllegalArgumentException if list is {@code null} or size is not 
strictly positive
+     */
+    public static <T> List<List<T>> partition(List<T> list, int size) {
+        if (list == null) {
+            throw new IllegalArgumentException("List must not be null");       
   
+        }
+        if (size <= 0) {
+            throw new IllegalArgumentException("Size must be greater than 0"); 
           
+        }
+        return new Partition<T>(list, size);
+    }
     
+    /**
+     * Provides a partition view on a {@link List}.
+     */
+    private static class Partition<T> extends AbstractList<List<T>> {
+        private final List<T> list;
+        private final int size;
+
+        private Partition(List<T> list, int size) {
+            this.list = list;
+            this.size = size;
+        }
+
+        public List<T> get(int index) {
+            int listSize = size();
+            if (listSize < 0) {
+                throw new IllegalArgumentException("negative size: " + 
listSize);           
+            }
+            if (index < 0) {
+                throw new IndexOutOfBoundsException("Index " + index + " must 
not be negative");         
+            }
+            if (index >= listSize) {
+                throw new IndexOutOfBoundsException("Index " + index + " must 
be less than size " +
+                                                    listSize);           
+            }           
+            int start = index * size;
+            int end = Math.min(start + size, list.size());
+            return list.subList(start, end);
+        }
+
+        public int size() {
+            return (list.size() + size - 1) / size;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            return list.isEmpty();
+        }
+    }
 }

Modified: 
commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/TestListUtils.java
URL: 
http://svn.apache.org/viewvc/commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/TestListUtils.java?rev=1374049&r1=1374048&r2=1374049&view=diff
==============================================================================
--- 
commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/TestListUtils.java
 (original)
+++ 
commons/proper/collections/trunk/src/test/java/org/apache/commons/collections/TestListUtils.java
 Thu Aug 16 20:50:27 2012
@@ -22,6 +22,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
+import junit.framework.Assert;
 import junit.framework.Test;
 
 import org.apache.commons.collections.functors.EqualPredicate;
@@ -30,12 +31,7 @@ import org.apache.commons.collections.li
 /**
  * Tests for ListUtils.
  *
- * @version $Revision$
- *
- * @author Stephen Colebourne
- * @author Neil O'Toole
- * @author Matthew Hawthorne
- * @author Dave Meikle
+ * @version $Id$
  */
 public class TestListUtils extends BulkTest {
 
@@ -297,4 +293,32 @@ public class TestListUtils extends BulkT
         assertEquals(ListUtils.indexOf(fullList, null), -1);
     }
     
+    public void testPartition() {
+        List<Integer> strings = new ArrayList<Integer>();
+        for (int i = 0; i <= 6; i++) {
+            strings.add(i);
+        }
+        
+        final List<List<Integer>> partition = ListUtils.partition(strings, 3);
+
+        assertNotNull(partition);
+        assertEquals(3, partition.size());
+        assertEquals(1, partition.get(2).size());
+        
+        try {
+            ListUtils.partition(null, 3);
+            Assert.fail("failed to check for null argument");
+        } catch (IllegalArgumentException e) {}
+        
+        try {
+            ListUtils.partition(strings, 0);
+            Assert.fail("failed to check for size argument");
+        } catch (IllegalArgumentException e) {}
+        
+        try {
+            ListUtils.partition(strings, -10);
+            Assert.fail("failed to check for size argument");
+        } catch (IllegalArgumentException e) {}
+        
+    }    
 }


Reply via email to