package org.limewire.collection;
import java.util.Collections;
import java.util.List;
import java.util.NoSuchElementException;
/**
* Partitions a list into sublists with equal size. The remainder items in the
* list are included with the last sublist. For example, list = {1,2,3,4,5} and 2
* partitions makes subList1 = {1,2} and subList2 = {3,4,5}.
<pre>
LinkedList<String> list = new LinkedList<String>();
for(int i = 1; i < 6; i++)
list.add(String.valueOf(i));
System.out.println(list);
ListPartitioner<String> lp = new ListPartitioner<String>(list, 2);
List<String> p1 = lp.getPartition(0);
List<String> p2 = lp.getPartition(1);
System.out.println("partition 1: " + p1);
System.out.println("partition 2: " + p2);
Output:
[1, 2, 3, 4, 5]
partition 1: [1, 2]
partition 2: [3, 4, 5]
</pre>
*/
// ListPartitioner could be easily made to implement Iterable<List<E>>
public class ListPartitioner<E> {
private final List<E> list;
private final int numPartitions;
public ListPartitioner(List<E> list, int numPartitions) {
assert numPartitions > 0;
this.list = list;
this.numPartitions = numPartitions;
}
public List<E> getPartition(int index) {
if (index >= numPartitions)
throw new NoSuchElementException();
if (numPartitions == 1)
return list;
if (list.isEmpty())
return Collections.emptyList();
int partitionSize = list.size() / numActivePartitions();
if (partitionSize * index >= list.size())
return Collections.emptyList();
// if the last partition is not full, extend it
int end = partitionSize * (index + 1);
if (list.size() - end <= partitionSize && index == numPartitions -1 )
end = list.size();
return list.subList(partitionSize * index, end);
}
public List<E> getLastPartition() {
return getPartition(numActivePartitions() - 1);
}
private int numActivePartitions() {
return Math.min(list.size(), numPartitions);
}
public List<E> getFirstPartition() {
return getPartition(0);
}
}