Solution: Growing the Bag

When add finds the backing array full, it calls grow to make room. A fixed-size array cannot change size, so growing means the same thing it means for DynamicArray: build a bigger array and copy the balls into it.

Solution

The solution is the same as DynamicArray.grow, with a BallColor[] instead of an int[]:

private void grow() {
  BallColor[] bigger = new BallColor[balls.length * 2];
  for (int i = 0; i < size; i++) {
    bigger[i] = balls[i];
  }
  balls = bigger;
}

We double the capacity, the same way DynamicArray does, so each grow leaves as many free slots as there are balls already in the bag.

We copy only up to size, since the unused slots hold no balls. For a BallColor[] those slots hold null.

grow is private. The client adds balls and draws balls, and it never asks the bag to resize.