1. Introduction
When working with index-based collections in Java, encountering IndexOutOfBoundsException is highly likely. This article will guide you through resolving this exception and provide best practices to prevent it.
2. What Java Says about IndexOutOfBoundsException
IndexOutOfBoundsException has two direct subclasses, namely ArrayIndexOutOfBoundsException and StringIndexOutOfBoundsException. According to the Javadoc, an IndexOutOfBoundsException is thrown to indicate that an index of some sort (such as to an array, to a string, or a vector) is out of range.
3. How to Reproduce
Let’s consider the following code snippet which creates an ArrayList:
List<Integer> list = new ArrayList<>();//empty list
Just like arrays, an ArrayList in Java is zero-indexed. This means that the first element is at index 0 and the last element is at index list.size() – 1. If you try to access an element out of this range, you will receive an IndexOutOfBoundsException.
List<Integer> list = new ArrayList<>();//empty list
int nonExistingValue = list.get(0);//list has no element => IndexOutOfBoundsException
The code above produces the following output:
Exception in thread "main" java.lang.IndexOutOfBoundsException: Index 0 out of bounds for length 0
at java.base/jdk.internal.util.Preconditions.outOfBounds(Preconditions.java:64)
at java.base/jdk.internal.util.Preconditions.outOfBoundsCheckIndex(Preconditions.java:70)
at java.base/jdk.internal.util.Preconditions.checkIndex(Preconditions.java:266)
at java.base/java.util.Objects.checkIndex(Objects.java:359)
at java.base/java.util.ArrayList.get(ArrayList.java:427)
at Scratch.main(scratch.java:7)
To fix the exception, you should make sure that the index is in the range of your ArrayList.
List<Integer> list = new ArrayList<>();//empty list => size = 0
list.add(5);//a new value is added => size = 1
int existingValue = list.get(0);//list has 1 element => No IndexOutOfBoundsException
Note that this exception in only raised when manipulating index-based collections like ArrayList and Vector.
4. Best Practices to Avoid IndexOutOfBoundsException
4.1. Check bounds before accessing elements
Always ensure that the index of the element you are trying to access is within the range [0, yourList.size() – 1].
ArrayList<String> list = new ArrayList<>();
int index = 3;
if (index >= 0 && index < list.size()) {//Boundaries check
String value = list.get(index);// Accessing element safely
// Do the thing
} else {
// Handle out-of-bounds access gracefully
}
Additionally, you should always check for emptiness before removing an element from the ArrayList:
if(!list.isEmpty()){
list.remove(0);
}
4.2. Use loops safely
Ensure that when iterating over an ArrayList using a loop, the loop’s start and end conditions fall within the valid range of ArrayList indexes.
ArrayList<String> list = new ArrayList<>();
for(int i=0; i < list.size(); i++){//Elements are within the range [0, list.size() - 1]
// Your code here
}
Always give special attention to edge cases as they often lead to IndexOutOfBoundsException
4.3. Prefer enhanced for-loop
To avoid dealing with indices, use the enhanced for-loop whenever possible.
List<String> list = new ArrayList<>();
for (String value : list) { //No index => No potential IndexOutOfBoundsException
// Your code here
}
5. Conclusion
In this brief tutorial, you learned about the IndexOutOfBoundsException and how to fix it.