Get a sublist of a list in Java
This post will discuss how to get a sublist of a list between two specified indexes in Java.
1. Naive solution
A naive solution is to add elements from the original list present between the specified indexes to the sublist.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
// Generic method to get a sublist of a list between two specified indexes public static<T> List<T> sublist(List<T> list, int start, int end) { // create an empty list List<T> subList = new ArrayList<>(); // add desired elements from the original list to the sublist for (int i = start; i <= end; i++) { subList.add(list.get(i)); } // return the sublist return subList; } |
2. Using List.sublist() method
We can also use the sublist() method provided by the List interface that returns a “view” of the portion of the list between the specified indexes.
|
1 2 3 4 |
// Generic method to get a sublist of a list between two specified indexes public static<T> List<T> sublist(List<T> list, int start, int end) { return list.subList(start, end + 1); } |
⮚ IndexOutOfBoundsException
The subList() method throws IndexOutOfBoundsException if starting or ending index is illegal. For instance,
- start < 0
- end > list.size()
- start > end
To avoid IndexOutOfBoundsException from happening, we can check if indexes are within proper bounds before passing to sublist(), as shown below:
|
1 2 3 4 |
// Generic method to get a sublist of a list between two specified indexes public static<T> List<T> sublist(List<T> list, int start, int end) { return list.subList(Math.max(0, start), Math.min(list.size(), end + 1)); } |
⮚ ConcurrentModificationException
Since the list returned by list.subList() is backed by the list, any non-structural changes (that do not change the size of the list) in the sublist are reflected in the original list and vice-versa. If the backing list is structurally modified in any way, the behavior of the list is undefined, and ConcurrentModificationException may be thrown.
|
1 2 3 4 5 6 7 8 |
// Generic method to get a sublist of a list between two specified indexes public static<T> List<T> sublist(List<T> list, int start, int end) { List<T> subList = list.subList(start, end + 1); list.remove(2); // lead to `ConcurrentModificationException` return subList; } |
Output:
Exception in thread “main” java.util.ConcurrentModificationException
at java.util.ArrayList$SubList.checkForComodification(ArrayList.java:1231)
at java.util.ArrayList$SubList.listIterator(ArrayList.java:1091)
at java.util.AbstractList.listIterator(AbstractList.java:299)
at java.util.ArrayList$SubList.iterator(ArrayList.java:1087)
at java.util.AbstractCollection.toString(AbstractCollection.java:454)
at java.lang.String.valueOf(String.java:2994)
at java.lang.StringBuilder.append(StringBuilder.java:131)
at Main.main(Main.java:23)
The solution to this problem is to create a new list from the returned view by subList(), as shown below:
|
1 2 3 4 5 6 7 8 |
// Generic method to get a sublist of a list between two specified indexes public static<T> List<T> sublist(List<T> list, int start, int end) { List<T> subList = new ArrayList<>(list.subList(start, end + 1)); list.remove(2); // ConcurrentModificationException not thrown return subList; } |
That’s all about getting a sublist of a list in Java.
Reference: List Javadoc SE 8
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 :)