Unit 07 · lesson

Index Boundaries Are Part of the Data Model

For an array of length 5, valid indexes are:

0, 1, 2, 3, 4

Index 5 is outside the array.

This is why the standard traversal condition is:

for (int i = 0; i < values.length; i++)

not:

for (int i = 0; i <= values.length; i++)

The upper boundary is exclusive.

A runtime failure that compiles cleanly

void main() {
    int[] values = {10, 20, 30};
    IO.println(values[3]);
}

The source is valid Java. values is an array and an integer index is legal syntax. At runtime, the requested position does not exist, so Java throws an index-related exception.

This is a good example of why static type correctness and valid runtime state are different questions.

Never derive a last index by guessing

Weak:

IO.println(values[2]);

Better when the intent is "last element":

IO.println(values[values.length - 1]);

The expression stays connected to the structure if the array length changes.

Empty arrays change the boundary

int[] values = {};

Now values.length is 0 and there is no last element. values[values.length - 1] becomes index -1, which is also invalid.

So the requirement "print the last element" carries a precondition:

array length must be greater than zero

Make it visible:

if (values.length == 0) {
    IO.println("NO VALUES");
} else {
    IO.println(values[values.length - 1]);
}

Search returns a position or absence

Write a method:

int findIndex(int[] values, int target) {
    for (int i = 0; i < values.length; i++) {
        if (values[i] == target) {
            return i;
        }
    }
    return -1;
}

The return contract uses -1 as a sentinel meaning "not found."

Test:

  • target is first element;
  • target is middle element;
  • target is last element;
  • target is absent;
  • array is empty.

Those cases prove more than five random middle values.

Fault injection

Start with a correct array traversal. Create one bad version using <= values.length.

Before running, identify:

  • the first invalid index;
  • the iteration on which it appears;
  • which earlier outputs will already have occurred;
  • the failure category.

Then run and compare.

Evidence

Produce a boundary test table for one array method. Include expected result and actual result for empty, first, middle, last, and absent conditions where applicable.

The purpose is to show that array correctness lives at the edges as much as in the normal case.