[COLLECTIONS-393] Added ListUtils.partition method, thanks to Chris Shayan for report and patch.
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/collections/trunk@1374049 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
a5c9272431
commit
b5715ec19d
|
@ -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>
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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.list.PredicatedList;
|
|||
/**
|
||||
* 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 BulkTest {
|
|||
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) {}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue