Split a list into two sublists in Java
This post will discuss how to split a list into two sublists using Java Collections, Java 8, Guava library, and Apache Common Collections.
1. Naive solution
A naive solution is to create two new empty lists and assign elements from the first half of the original list to the first list and elements from the second half of the original list to the second list.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
// Generic method to split a list into two sublists in Java public static<T> List[] split(List<T> list) { // create two empty lists List<T> first = new ArrayList(); List<T> second = new ArrayList(); // get the size of the list int size = list.size(); // process each list element and add it to the first list // or second list based on its position for (int i = 0; i < size; i++) { if (i < (size + 1)/2) { first.add(list.get(i)); } else { second.add(list.get(i)); } } // return a list array to accommodate both lists return new List[] {first, second}; } |
2. Using List.subList() method
This is the recommended approach in Java SE, where we use the List.subList() method that returns a view of this list between the specified indexes. Since this list backs the returned list, we can construct a new list from the returned view, as shown below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
// Generic method to split a list into two sublists in Java public static<T> List[] split(List<T> list) { // get the size of the list int size = list.size(); // construct a new list from the returned view by `List.subList()` method List<T> first = new ArrayList<>(list.subList(0, (size + 1)/2)); List<T> second = new ArrayList<>(list.subList((size + 1)/2, size)); // return an array of lists to accommodate both lists return new List[] {first, second}; } |
3. Using Java 8 Stream
⮚ Collectors partitioningBy
We can use Collectors.partitioningBy() to split the list into two sublists in Java 8 and above, as shown below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Generic method to split a list into two sublists in Java 8 and above public static<T> List[] split(List<T> list) { int midIndex = (list.size() - 1) / 2; List<List<T>> lists = new ArrayList<>( list.stream() .collect(Collectors.partitioningBy(s -> list.indexOf(s) > midIndex)) .values() ); // return an array containing both lists return new List[] {lists.get(0), lists.get(1)}; } |
Similar to Collectors.partitioningBy(), we can use Collectors.groupingBy() to split the list into two sublists, as shown below:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Generic method to split a list into two sublists in Java 8 and above public static<T> List[] split(List<T> list) { int midIndex = (list.size() - 1) / 2; List<List<T>> lists = new ArrayList<>( list.stream() .collect(Collectors.groupingBy(s -> list.indexOf(s) > midIndex)) .values() ); // return an array containing both lists return new List[] {lists.get(0), lists.get(1)}; } |
⮚ List.subList()
This is just an alternative way in Java 8, and above to split the list using the list.subList() method discussed earlier.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Generic method to split a list into two sublists in Java 8 and above public static<T> List[] split(List<T> list) { // endpoints to use in `list.subList()` method int[] endpoints = {0, (list.size() + 1)/2, list.size()}; List<List<T>> lists = IntStream.rangeClosed(0, 1) .mapToObj(i -> list.subList(endpoints[i], endpoints[i + 1])) .collect(Collectors.toList()); // return an array containing both lists return new List[] {lists.get(0), lists.get(1)}; } |
4. Using Guava Library
With the Guava library, we can use the Lists.partition() method that splits the list into consecutive sublists, each of the specified size. To split the list into two sublists, we can pass the size equal to half the size of our list.
|
1 2 3 4 5 6 7 8 9 |
// Generic method to split a list into two sublists in Java using Guava public static<T> List[] split(List<T> list) { // partition the list into two sublists List<List<T>> lists = Lists.partition(list, (list.size() + 1) / 2); // return an array containing both lists return new List[] {lists.get(0), lists.get(1)}; } |
Guava’s Iterables class contains a static utility method partition(Iterable<T>, int) that divides an iterable into unmodifiable sublists of the given size.
We can use this method to split our list into two sublists, but since the returned sublists are unmodifiable, we can construct new mutable lists from the returned sublists, as shown below:
|
1 2 3 4 5 6 7 8 9 10 |
// Generic method to split a list into two sublists in Java using Guava public static<T> List[] split(List<T> list) { // partition the list into two sublists and get an iterator Iterator<List<T>> itr = Iterables.partition(list, (list.size() + 1) / 2) .iterator(); // return an array containing both lists return new List[] {new ArrayList<>(itr.next()), new ArrayList<>(itr.next())}; } |
5. Using Apache Commons Collections
Apache Commons Collections also provides a ListUtils.partition() method that has exact functionality as Guava’s Lists.partition() method.
|
1 2 3 4 5 6 7 8 9 |
// Generic method to split a list using Apache Commons Collections public static<T> List[] split(List<T> list) { // partition the list into two sublists List<List<T>> lists = ListUtils.partition(list, (list.size() + 1) / 2); // return an array containing both lists return new List[] {lists.get(0), lists.get(1)}; } |
That’s all about splitting a list into two sublists in Java.
Related Article:
Thanks for reading.
To share your code in the comments, please use our online compiler that supports C, C++, Java, Python, JavaScript, C#, PHP, and many more popular programming languages.
Like us? Refer us to your friends and support our growth. Happy coding :)