Exercise

Exercise:

  • Update the specification/declaration of IndexedList.put to make it robust.
  • Write unit tests for put to check exception is thrown when it is expected.
  • Update implementation of ArrayIndexedList.put to throw exception.
Solution

Update IndexedList.put:

/**
 * Change the value at the given index.
 *
 * @param index representing a position in this list.
 * @param value to be written at the given index.
 *              Post: this.get(index) == value
 * @throws IndexOutOfBoundsException when index < 0 or index >= length.
 */
void put(int index, T value) throws IndexOutOfBoundsException;

Add the following unit tests to IndexedListTest:

@Test
@DisplayName("put() throws exception if index is below the valid range.")
void testPutWithIndexBelowRangeThrowsException() {
  try {
    numbers.put(-1, 10);
    fail("IndexOutOfBoundsException was not thrown for index < 0");
  } catch (IndexOutOfBoundsException ex) {
    return;
  }
}

@Test
@DisplayName("put() throws exception if index is above the valid range.")
void testPutWithIndexAboveRangeThrowsException() {
  try {
    numbers.put(size + 1, 10);
    fail("IndexOutOfBoundsException was not thrown for index > length");
  } catch (IndexOutOfBoundsException ex) {
    return;
  }
}

Update ArrayIndexedList.put:

@Override
public void put(int index, T value) throws IndexOutOfBoundsException {
  if (index < 0 || index > length()) {
    throw new IndexOutOfBoundsException();
  }
  
  data[index] = value;
}

Aside: IndexOutOfBoundsException is a built-in Java Exception which will be thrown e.g. when an array is indexed with a value out of index range. So, the statement data[index] = value; will throw IndexOutOfBoundsException when index is invalid; we didn't need to change the implementation of ArrayIndexedList.put. I prefer the updated implementation as it provides more clarity to the behavior of the method.