Where Off-by-One Hides
Scenario #1
Loop Bound: <= vs < With .length
An array with 5 elements has indices 0–4. Using <= with .length attempts index 5.
int[] arr = {10, 20, 30, 40, 50};
for (int i = 0; i <= arr.length; i++) // i goes to 5
{
System.out.println(arr[i]); // crashes at i=5
}
CORRECT
for (int i = 0; i < arr.length; i++) // i goes to 4
{
System.out.println(arr[i]);
}
i < array.length or i < list.size(). If you see <=, it is almost certainly a bug.Scenario #2
Starting at 1 Instead of 0
Java arrays are zero-indexed. Starting a loop at i = 1 skips the first element entirely.
int sum = 0;
for (int i = 1; i < arr.length; i++)
{
sum += arr[i];
}
// Misses arr[0] entirely
arr[i] with arr[i-1], or when you initialized max = arr[0] and only need to check the rest.Scenario #3
Adjacent Comparison: Stopping Too Late
When comparing each element with its neighbor, the loop must stop one element early. Otherwise arr[i+1] goes out of bounds.
for (int i = 0; i < arr.length; i++)
{
if (arr[i] == arr[i + 1]) // i+1 out of bounds on last pass
{
System.out.println("Duplicate at " + i);
}
}
CORRECT
for (int i = 0; i < arr.length - 1; i++)
{
if (arr[i] == arr[i + 1])
{
System.out.println("Duplicate at " + i);
}
}
arr[i+1] or arr[i-1] inside a loop, adjust the loop bounds accordingly. i+1 requires i < length - 1. i-1 requires i >= 1.Scenario #4
String substring() — End Index Is Exclusive
substring(start, end) returns characters from start up to but not including end. Students forget the end is exclusive and extract one character too few or too many.
String word = "HELLO"; System.out.println(word.substring(1, 3)); // Prints "EL" (indices 1 and 2, NOT 1, 2, and 3) // To get single char at index i (2026 curriculum uses substring): String ch = word.substring(i, i + 1);
charAt() is not on the 2026 Quick Reference. Use substring(i, i + 1) to extract a single character as a String.Eliminate Off-by-One Errors for Good
The Cram Kit includes targeted drills on loop bounds and traversal patterns.
Get the Cram Kit — $29.99 1-on-1 TutoringScenario #5
2D Arrays: Wrong Dimension for Loop Bound
Using grid.length for the column loop or grid[0].length for the row loop causes out-of-bounds on non-square grids.
int[][] grid = new int[3][5]; // 3 rows, 5 cols
// WRONG: using grid[0].length (5) for row bound
for (int r = 0; r < grid[0].length; r++) // goes to 4, but only rows 0-2
{
// crashes at r=3
}
grid.length. Columns = grid[0].length. Write it on your scratch paper before every 2D array problem.Scenario #6
Fencepost: Counting Gaps vs Posts
If you have 5 fence posts, you have 4 gaps between them. This pattern shows up when counting pairs, intervals, or separators.
// Printing elements separated by commas (no trailing comma)
for (int i = 0; i < arr.length; i++)
{
System.out.print(arr[i]);
if (i < arr.length - 1)
{
System.out.print(", ");
}
}
// For {1,2,3}: prints "1, 2, 3" not "1, 2, 3, "
length - 1, not length.Ready to Stop Losing Points?
54.5% of my students score 5s. Get the help you need before May 15.
4-Week Cram Kit — $29.99 Book Tutoring