Generic Array

The constructor of ArrayIndexedList must instantiate and initialize data, the generic array. In a perfect world, this would be identical to using any other (primitive or reference) type:

public ArrayIndexedList(int size, T defaultValue) {
  data = new T[size];
  for (int i = 0; i < size; i++) {
    data[i] = defaultValue;
  }
}

But the statement new T[size] will not work! It results in a compiler error. You must instead do this:

data = (T[]) new Object[size];

So, you must create an array of Object and then cast it to a generic array. This latter strategy is a workaround to create generic arrays. It results in a compilation warning (Unchecked cast: java.lang.Object[] to T[]) which you may ignore.

The reasons to which Java is unable to create a generic array (as in new T[size]) is irrelevant to the study of data structures (it has to do with how Java's compiler works).

Aside: Here is another syntax for creating generic arrays:

data = (T[]) Array.newInstance(Object.class, size);

There is no preference is using either syntax. The Array.newInstance under the hood does the same thing as the syntax presented earlier.

Resources

If you are anxious to better understand why we instantiate a generic array as data = (T[]) new Object[size];, it has to do with how the following two processes (common to compiler implementation) are implemented in Java's compiler: erasure and reification. These are, as mentioned before, irrelevant to the study of data structures. I know, for many of you, your curiosity is not satisfied until you understand these. Here are some resources if you are interested to learn more:

This is the book that helped me to understand it:

Naftalin, Maurice, and Philip Wadler. Java generics and collections. Sebastopol, Calif: O'Reilly, 2006. Print.

It is enough to read the first four chapters to understand how type erasure and reification work in Java.