How to Divide Lists into Sublists of Size N in Java
How can we divide lists into sublists of some size n
in Java?
In other words, how can we partition lists into multiple sublists?
Suppose we want to process a sublist of our list in this processBatch()
method.
void processBatch(List<Object> batch) { /* Process batch */ }
We might also have a List<Object> list
and int batchSize
.
1. Using Guava’s Lists.partition()
We can create the partitioned list using Lists.partition()
, then process a batch on each iteration.
for (List<Object> batch : Lists.partition(list, batchSize)) {
processBatch(batch);
}
We can also run this batch through a forEach()
.
Lists.partition(list, batchSize).forEach(this::processBatch);
2. Using Guava’s Iterators.partition()
If we’re working with a collection, but not a list, we can use Iterators.partition()
.
Similar to Lists.partition()
, we can use a simple loop.
for (List<Object> batch : Iterators.partition(collection, batchSize)) {
processBatch(batch);
}
Or, a forEach()
.
Iterators.partition(collection, batchSize).forEach(this::processBatch);
Guava
Lists
vsIterators
? If the list is an instance of theRandomAccess
interface, thenLists
will offer a performance benefit.
3. Using Apache Commons' ListUtils.partition()
Apache Commons' ListUtils
functions the same way.
ListUtils.partition(list, batchSize).forEach(this::processBatch);
4. Using manual partitioning
We can also manually create the partitions.
List<List<Object>> batches = new ArrayList<>();
for (int i = 0; i < list.size(); i += batchSize) {
batches.add(list.subList(i, Math.min(i + batchSize, list.size())));
}
Let’s try doing the same thing using streams.
List<List<Object>> batches = IntStream.range(0, list.size())
.filter(i -> i % batchSize == 0)
.mapToObj(i -> list.subList(i, Math.min(i + batchSize, list.size())))
.collect(Collectors.toList());
Once the list of lists is created, we can simply iterate through and process each batch.
for (List<Object> batch : batches) {
processBatch(batch)
}