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
ListsvsIterators? If the list is an instance of theRandomAccessinterface, thenListswill 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)
}