How to Split a List Into Chunks in Java
-
Use the
List.subList()
Method to Split a List Into Chunks in Java - Use Java Streams to Split a List Into Chunks in Java
-
Use the
Collectors.groupingBy()
Method to Split a List Into Chunks in Java - Use Apache Commons Collections Method to Split a List Into Chunks in Java
- Use Google Guava Library to Split a List Into Chunks in Java
- Conclusion
Splitting a list into smaller chunks is a common operation in Java, especially when dealing with large datasets or when implementing certain algorithms that require processing data in smaller portions. There are several approaches to achieve this in Java, each with its advantages and use cases.
Sometimes, it is required to split a list into a particular size of chunks in Java. This tutorial demonstrates different methods to split a list into chunks in Java.
Use the List.subList()
Method to Split a List Into Chunks in Java
The subList()
method in Java’s List
interface allows us to create a view of a portion of an existing list. It takes two parameters: the starting index (inclusive) and the ending index (exclusive) of the sublist to be retrieved.
The resulting sublist is a view
of the original list, meaning it maintains a reference to the original list’s elements without creating a new copy.
Syntax:
List<E> subList(int fromIndex, int toIndex)
fromIndex
: The starting index (inclusive) of the sublist. The index of the first element in the sublist.toIndex
: The ending index (exclusive) of the sublist. The index after the last element in the sublist.
This method returns a view of the original list that contains elements from fromIndex
up to toIndex - 1
. The sublist is a view
in the sense that it references the original list’s elements, allowing modifications in the sublist to affect the original list and vice versa.
For example:
list.subList(2, 5)
returns a sublist that includes elements at indices2
,3
, and4
from the original list.- The sublist includes elements starting from
fromIndex
up to, but not including,toIndex
.
Keep in mind that if the original list is modified structurally (such as adding or removing elements) after creating a sublist, it can lead to unexpected behavior, including ConcurrentModificationException
. Therefore, caution should be exercised when manipulating both the original list and its sublists simultaneously.
The List.subList
method can be used along with a for
loop to split a list into a particular size of chunks in Java. The subList()
method will get a sublist from the given list within a specific start and end index.
Let’s see an example:
package delftstack;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Example {
public static void main(String[] args) {
List<Integer> DemoList = IntStream.rangeClosed(100, 120).boxed().collect(Collectors.toList());
int ChunkSize = 3;
List<List<Integer>> Chunks = new ArrayList<>();
for (int x = 0; x < DemoList.size(); x += ChunkSize) {
Chunks.add(DemoList.subList(x, Math.min(x + ChunkSize, DemoList.size())));
}
System.out.println(Chunks);
}
}
The code generates a list of integers from 100
to 120
and then splits this list into smaller chunks of size 3
using the subList()
method. It iterates through the original list, creating sublists of the specified size and storing them in an ArrayList
.
The code above will create chunks of size three from the given list. See the output:
This demonstrates a straightforward approach to dividing a list into smaller segments in Java, which is useful for managing and processing data in batches.
Use Java Streams to Split a List Into Chunks in Java
Similarly, we can use Java 9 IntStream.iterate()
to split a list into chunks in Java.
The IntStream.iterate()
method in Java creates an ordered sequence of primitive int-valued elements. It starts with an initial value (seed
) and generates subsequent elements by applying a function to the previous element.
Syntax:
static IntStream iterate(int seed, IntUnaryOperator f)
seed
: The initial value from which the iteration starts.f
: AnIntUnaryOperator
function that takes an integer and produces the next integer in the sequence.
Java Streams provide a functional and concise way to perform operations on collections. Splitting a list into smaller chunks using Java Streams involves leveraging functionalities like IntStream
and collect()
with Collectors.toList()
.
See the example:
package delftstack;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Example {
private static <T> List<List<T>> Chunks(List<T> DemoList, int ChunkSize) {
return IntStream.iterate(0, x -> x < DemoList.size(), x -> x + ChunkSize)
.mapToObj(x -> DemoList.subList(x, Math.min(x + ChunkSize, DemoList.size())))
.collect(Collectors.toList());
}
public static void main(String[] args) {
List<Integer> DemoList = IntStream.rangeClosed(100, 120).boxed().collect(Collectors.toList());
int ChunkSize = 3;
List<List<Integer>> Chunks = Chunks(DemoList, ChunkSize);
System.out.println(Chunks);
}
}
The code above will use IntStream.iterate()
from Java 9 to perform the same operation as the previous method.
This code demonstrates how to split a list into chunks using Java Streams. The Chunks
method takes a list (DemoList
) and a chunk size (ChunkSize
) as input and returns a list of lists representing the divided chunks.
This code efficiently utilizes Java Streams (IntStream.iterate()
, mapToObj()
, and collect()
) to split the input list (DemoList
) into smaller chunks based on the specified chunk size. The output displays the divided chunks as a list of lists.
We can also use Java 8 Stream
API to perform the same operation. See example:
package delftstack;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Example {
private static <T> List<List<T>> Chunk(List<T> DemoList, int ChunkSize) {
return IntStream.rangeClosed(0, (DemoList.size() - 1) / ChunkSize)
.mapToObj(
x -> DemoList.subList(x * ChunkSize, Math.min((x + 1) * ChunkSize, DemoList.size())))
.collect(Collectors.toList());
}
public static void main(String[] args) {
List<Integer> DemoList = IntStream.rangeClosed(100, 120).boxed().collect(Collectors.toList());
int ChunkSize = 3;
List<List<Integer>> Chunks = Chunk(DemoList, ChunkSize);
System.out.println(Chunks);
}
}
The code above will use Java 8 Stream
API to split the list into three chunks. It demonstrates a method called Chunk
within the Example
class that splits a list (DemoList
) into smaller sublists of a specified size (ChunkSize
).
This code demonstrates an elegant use of Java Streams, specifically IntStream.rangeClosed
, mapToObj
, and collect
, to efficiently split a list into smaller chunks based on a specified size, providing a reusable method for chunking lists.
See the output:
Use the Collectors.groupingBy()
Method to Split a List Into Chunks in Java
The Collectors.groupingBy()
method from Java Stream
API can also be used to split a list into chunks, where we group by list elements to create chunks. This method will return the chunks in the form of Maps
.
The Collectors.groupingBy()
method is a powerful collector that allows you to partition elements of a Stream
into groups based on a provided classification function. It returns a Map
where the keys represent the grouping criteria, and the values are lists of elements that match each criterion.
Syntax:
Map<K, List<T>> result = yourStream.collect(
Collectors.groupingBy(classifierFunction, // Function defining the grouping criterion
downstreamCollector // Optional downstream collector (e.g., Collectors.toList())
));
yourStream
: Represents the Stream instance containing elements to be grouped.classifierFunction
: This is a function that defines the criterion for grouping elements. It maps elements of the stream to keys of the resulting map. For example, if you want to group integers by their remainders when divided by3
, the classifier function might be:i -> i % 3
.downstreamCollector
(Optional): This parameter specifies a downstream collector, allowing further operations on the grouped elements. For instance,Collectors.toList()
collects the elements into a list for each group. It’s optional and can be omitted if you only need to group elements without any additional operations on the grouped values.Map<K, List<T>> result
: Represents the resulting map where keys of typeK
are the group criteria and values of typeList<T>
are the grouped elements.
Let’s see an example:
package delftstack;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Example {
private static <T> Collection<List<T>> Chunk(List<T> DemoList, int GroupBy) {
return IntStream.range(0, DemoList.size())
.boxed()
.collect(Collectors.groupingBy(
x -> x / GroupBy, Collectors.mapping(DemoList::get, Collectors.toList())))
.values();
}
public static void main(String[] args) {
List<Integer> DemoList = IntStream.rangeClosed(100, 120).boxed().collect(Collectors.toList());
int ChunkSize = 3;
Collection<List<Integer>> Chunks = Chunk(DemoList, ChunkSize);
System.out.println(Chunks);
}
}
This code demonstrates a method that efficiently partitions a list (DemoList
) into chunks of a specified size (ChunkSize
). It leverages Java Streams and collectors, particularly Collectors.groupingBy()
, to perform the chunking operation based on indices and collect elements into separate lists within a collection.
The main()
method showcases how to use this Chunk()
method with a sample list of integers and print the resulting chunks.
See the output:
Similarly, we can simplify the above code by using a mutable counter. See the example:
package delftstack;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Example {
private static <T> Collection<List<T>> Chunk(List<T> DemoList, int Groupby) {
AtomicInteger counter = new AtomicInteger();
return DemoList.stream()
.collect(Collectors.groupingBy(it -> counter.getAndIncrement() / Groupby))
.values();
}
public static void main(String[] args) {
List<Integer> DemoList = IntStream.rangeClosed(100, 120).boxed().collect(Collectors.toList());
int ChunkSize = 3;
Collection<List<Integer>> Chunks = Chunk(DemoList, ChunkSize);
System.out.println(Chunks);
}
}
The code above uses the mutable counter AtomicInteger
to group by the list to create chunks of size three. It efficiently divides a given list into smaller chunks of a specified size using Java Streams and the Collectors.groupingBy
collector, leveraging the index-based grouping technique.
See the output:
Use Apache Commons Collections Method to Split a List Into Chunks in Java
The Apache Commons is a third-party library that provides many operations, including a list. The collection from Apache Commons can also be used to create chunks of lists in Java.
First, make sure the Apache Commons Collections is added to your build path. Let’s try an example to create chunks of the list using Apache Commons Collections:
package delftstack;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.apache.commons.collections4.ListUtils;
public class Example {
public static void main(String[] args) {
List<Integer> DemoList = IntStream.rangeClosed(100, 120).boxed().collect(Collectors.toList());
int ChunkSize = 3;
List<List<Integer>> Chunks = ListUtils.partition(DemoList, ChunkSize);
System.out.println(Chunks);
}
}
The Apache Commons provides a method called partition
, which is used to create chunks of the given list. This code demonstrates how to split a list of integers (DemoList
) into smaller chunks of a specified size (ChunkSize
) using the ListUtils.partition
method from Apache Commons Collections.
The resulting chunks are stored in a list (Chunks
) and displayed as output in the console when the code is executed.
Use Google Guava Library to Split a List Into Chunks in Java
The Guava package from Google also provides many functionalities regarding lists in Java. It provides a method, Lists.partition()
, used to create chunks of a list in Java.
Please make sure the Guava package is added to your build path because it is a third-party package and not included in JDK. Let’s try an example:
package delftstack;
import com.google.common.collect.Lists;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class Example {
public static void main(String[] args) {
List<Integer> DemoList = IntStream.rangeClosed(100, 120).boxed().collect(Collectors.toList());
int ChunkSize = 3;
List<List<Integer>> Chunk = Lists.partition(DemoList, ChunkSize);
System.out.println(Chunk);
}
}
The code above will similarly create chunks of the given list in the form of three using the Guava library partition()
method. It showcases the usage of Google Guava’s Lists.partition()
method to efficiently split a list of integers into smaller chunks.
Google Guava provides a concise and convenient way to perform this operation without manually writing code for chunking. The resulting chunks are stored in a list and can be further utilized or processed based on the program’s requirements.
Conclusion
The tutorial explores diverse methods for splitting lists in Java into smaller chunks:
- List Subdivision (
List.subList()
):- Uses the
subList()
method to create view sublists based on indices, offering an efficient way to segment a list without copying elements.
- Uses the
- Java Streams Approach:
- Showcases Java 8 and Java 9 Streams (
IntStream.iterate()
andIntStream.rangeClosed()
) to split lists into chunks based on specified sizes, providing concise functional solutions.
- Showcases Java 8 and Java 9 Streams (
Collectors.groupingBy()
from Java Stream API:- Highlights the powerful
Collectors.groupingBy()
method to categorize elements into chunks based on custom criteria, producing aMap
of grouped elements.
- Highlights the powerful
- Third-party Libraries (Apache Commons Collections & Google Guava):
- Introduces third-party methods (
ListUtils.partition()
from Apache Commons Collections andLists.partition()
from Google Guava) to simplify list splitting, offering convenient alternatives without custom logic.
- Introduces third-party methods (
Each method provides unique advantages, catering to different use cases and preferences and empowering developers to efficiently segment lists as needed.
Sheeraz is a Doctorate fellow in Computer Science at Northwestern Polytechnical University, Xian, China. He has 7 years of Software Development experience in AI, Web, Database, and Desktop technologies. He writes tutorials in Java, PHP, Python, GoLang, R, etc., to help beginners learn the field of Computer Science.
LinkedIn Facebook