In Java, a sublist is a portion of an existing list containing elements from a specific range of indexes. The subList() method of the List interface can be used to easily obtain a sublist.
- The starting index is inclusive, while the ending index is exclusive.
- The returned sublist is backed by the original list.
- Invalid indexes can result in IndexOutOfBoundsException or IllegalArgumentException.
- We access the list through their index numbers called Interface that we won't be discussing here.
For example, consider the following list:
[10, 20, 30, 40, 50, 60]
A sublist containing elements from index 1 to 4 is:
[20, 30, 40]
Here, index 1 is included, while index 4 is excluded.
Methods to Find a Sublist in a List
1. Using subList() Method
The simplest way to find a sublist is to use the subList() method provided by the List interface.
Approach
- Create a list and add elements to it.
- Specify the starting and ending indexes.
- Use subList() to obtain the required portion of the list.
- Print the resulting sublist.
import java.util.ArrayList;
import java.util.List;
public class FindSublist{
public static void main(String[] args){
// Create a list
List<Integer> list = new ArrayList<>();
// Add elements to the list
list.add(15);
list.add(25);
list.add(35);
list.add(45);
list.add(55);
list.add(65);
// Display the original list
System.out.println("Original List: " + list);
// Find sublist from index 2 to 5
// Index 2 is included and index 5 is excluded
List<Integer> sublist = list.subList(2, 5);
// Display the sublist
System.out.println("Sublist: " + sublist);
}
}
Output
Original List: [15, 25, 35, 45, 55, 65] Sublist: [35, 45, 55]
Explanation: The subList() method is used to extract a portion of the original list from the specified starting index to the ending index.Here, subList(2, 5) includes elements at indexes 2, 3, and 4, while index 5 is excluded.
2.Using a Loop
We can also find a sublist manually using a loop. This approach is useful for understanding how elements are selected based on their indexes.
Approach
- Create the original list.
- Create an empty list to store the sublist.
- Traverse the original list from fromIndex to toIndex - 1.
- Add each selected element to the new list.
- Print the resulting sublist.
import java.util.ArrayList;
import java.util.List;
public class FindSublist {
public static void main(String[] args){
// Create the original list
List<String> list = new ArrayList<>();
list.add("Java");
list.add("Python");
list.add("C++");
list.add("JavaScript");
list.add("Kotlin");
list.add("Go");
// Create an empty list for the sublist
List<String> sublist = new ArrayList<>();
int fromIndex = 1;
int toIndex = 5;
// Traverse from fromIndex to toIndex - 1
for (int i = fromIndex; i < toIndex; i++){
sublist.add(list.get(i));
}
System.out.println("Original List: " + list);
System.out.println("Sublist: " + sublist);
}
}
Output
Original List: [Java, Python, C++, JavaScript, Kotlin, Go] Sublist: [Python, C++, JavaScript, Kotlin]
Explanation: The program creates a sublist manually by traversing the original list from fromIndex to toIndex - 1 and adding each element to the new list. Here, elements at indexes 1, 2, 3, and 4 are copied into the sublist, while index 5 is excluded.
3. Using ArrayList Constructor with subList()
The subList() method returns a view of the original list. If we want an independent list, we can pass the sublist to the ArrayList constructor.
Approach
- Create the original list.
- Use subList() to select the required range.
- Pass the returned sublist to the ArrayList constructor.
- Store it as a new independent list.
import java.util.ArrayList;
import java.util.List;
public class IndependentSublist {
public static void main(String[] args){
// Create the original list
List<Integer> list = new ArrayList<>();
list.add(5);
list.add(10);
list.add(15);
list.add(20);
list.add(25);
list.add(30);
// Create an independent list from the sublist
List<Integer> sublist =
new ArrayList<>(list.subList(1, 4));
System.out.println("Original List: " + list);
System.out.println("Sublist: " + sublist);
// Modify the new list
sublist.set(0, 100);
System.out.println("After modifying sublist:");
System.out.println("Original List: " + list);
System.out.println("Sublist: " + sublist);
}
}
Output
Original List: [5, 10, 15, 20, 25, 30] Sublist: [10, 15, 20] After modifying sublist: Original List: [5, 10, 15, 20, 25, 30] Sublist: [100, 15, 20]
Explanation: The program creates an independent sublist using new ArrayList<>(list.subList(1, 4)), so changes made to the sublist do not affect the original list. Here, changing the first element of the sublist to 100 only modifies the sublist, while the original list remains unchanged.
4. Using Java Streams
Java Streams can also be used to select elements whose indexes fall within a specified range.
Approach
- Create the original list.
- Generate a stream of indexes.
- Select only indexes between fromIndex and toIndex.
- Map the indexes to their corresponding elements.
- Collect the elements into a new list.
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class StreamSublist{
public static void main(String[] args){
// Create the original list
List<String> list = new ArrayList<>();
list.add("HTML");
list.add("CSS");
list.add("JavaScript");
list.add("Java");
list.add("Python");
list.add("SQL");
int fromIndex = 2;
int toIndex = 5;
// Find the sublist using streams
List<String> sublist = IntStream
.range(fromIndex, toIndex)
.mapToObj(list::get)
.collect(Collectors.toList());
System.out.println("Original List: " + list);
System.out.println("Sublist: " + sublist);
}
}
Output
Original List: [HTML, CSS, JavaScript, Java, Python, SQL] Sublist: [JavaScript, Java, Python]
Explanation: The program uses Java Streams with IntStream.range() to generate indexes from fromIndex to toIndex - 1, and mapToObj() retrieves the corresponding elements from the list. Here, indexes 2, 3, and 4 are collected into a new list using Collectors.toList(), producing the required sublist.
Handling Invalid Indexes
The indexes supplied to subList() must follow these conditions:
0 <= fromIndex <= toIndex <= list.size()
If these conditions are not satisfied, an exception is thrown.
1. IllegalArgumentException
import java.util.ArrayList;
import java.util.List;
public class InvalidSublist {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
list.add(30);
list.add(40);
// fromIndex is greater than toIndex
List<Integer> sublist = list.subList(3, 1);
System.out.println(sublist);
}
}
Output: Exception in thread "main" java.lang.IllegalArgumentException
Explanation: In Above Code, fromIndex is 3, while toIndex is 1. Since the starting index cannot be greater than the ending index, Java throws an IllegalArgumentException.
2. IndexOutOfBoundsException
import java.util.ArrayList;
import java.util.List;
public class InvalidSublist {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(10);
list.add(20);
list.add(30);
list.add(40);
// toIndex is outside the valid range
List<Integer> sublist = list.subList(1, 6);
System.out.println(sublist);
}
}
Output: Exception in thread "main" java.lang.IndexOutOfBoundsException
Explanation: The list contains only four elements, so the valid indexes range from 0 to 3. Since toIndex is 6, the specified range is invalid and an IndexOutOfBoundsException is thrown.