Reviewing custom array List class of java I am using JDK 12 and  I have developed the custom array list in java with a basic understanding Please let me know if there are any flaws in it that I can correct the same

First the POJO class

public class Employee {
    private String id;
    private String name;

    public Employee(String id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "Employee[id=" + id + ", name=" + name + "] ";
    }

}


Then come the main logic class of ArrayList, which is the heart 

class CustomArrayList&lt;E&gt; {

    private static final int INITIAL_CAPACITY = 10;
    private Object[] elementData;
    private int size = 0;


    public customArrayList() {
        elementData = new Object[INITIAL_CAPACITY];
    }


    private void ensureCapacity() {
        int newIncreasedCapacity = elementData.length * 2;
        elementData = Arrays.copyOf(elementData, newIncreasedCapacity);
    }


    public void add(E e) {
        if (size == elementData.length) {
            ensureCapacity();
        }
        elementData[size++] = e;
    }


    @SuppressWarnings("unchecked")
    public E get(int index) {
        if (index &lt; 0 || index &gt;= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size " + index);
        }
        return (E) elementData[index];
    }


    public Object remove(int index) {
        if (index &lt; 0 || index &gt;= size) {
            throw new IndexOutOfBoundsException("Index: " + index + ", Size " + index);
        }

        Object removedElement = elementData[index];
        for (int i = index; i &lt; size - 1; i++) {
            elementData[i] = elementData[i + 1];
        }
        size--;   //reduce size of ArrayListCustom after removal of element.
        return removedElement;
    }


    /**
     * method displays all the elements in list.
     */
    public void display() {
        System.out.print("Displaying list : ");
        for (int i = 0; i &lt; size; i++) {
            System.out.print(elementData[i] + " ");
        }
    }

}


and finally, the test class to test the custom implementation of the ArrayList 

public class ArrayListTest {

    public static void main(String... a) {
        CustomArrayList&lt;Employee&gt; list = new CustomArrayList&lt;&gt;();
        list.add(new Employee("1", "saral"));
        list.add(new Employee("2", "amit"));
        list.add(new Employee("3", "dinesh"));
        list.add(null);
        list.display();
        System.out.printf("\n element at index %d = %s%n", 1, list.get(1));
        System.out.printf("element removed from index %d = %s%n", 1, list.remove(1));

        System.out.println("\n" +
                "let's display list again after removal at index 1");
        list.display();

    }

}
The CustomArrayList API is inconsistent because I can declare a list of type E to add elements of type E, but when I remove an element from it, I get an Object element:


public Object remove(int index) { /* ... */ }





Inside CustomArrayList you work with Object[] elementData. From the book Effective Java; Item 26 you could change your code to:

class CustomArrayList&lt;E&gt; {

  private E[] elementData;
  /* ... */

  public CustomArrayList() {
    elementData = (E[]) new Object[INITIAL_CAPACITY];
  }

  /* ... */

}




Inside remove you modify elementData in an imperative way. You could use System.arraycopy which would be more deklarative.


public Object remove(int index) {
 /* ... */
 Object removedElement = elementData[index];
 for (int i = index; i &lt; size - 1; i++) {
   elementData[i] = elementData[i + 1];
 }
 /* ... */
}



public E remove(int index) {
  /* ... */

  if (size - 1 - index &gt;= 0)
    System.arraycopy(elementData, index + 1, elementData, index, size - 1 - index);

  /* ... */
}




The methods get and remove contain a code duplication:


public E get(int index) {
 if (index &lt; 0 || index &gt;= size) {
   throw new IndexOutOfBoundsException("Index: " + index + ", Size " + index);
  }
 return (E) elementData[index];
}

public Object remove(int index) {
 if (index &lt; 0 || index &gt;= size) {
   throw new IndexOutOfBoundsException("Index: " + index + ", Size " + index);
 }

 Object removedElement = elementData[index];

 /* ... */

 return removedElement;
}



It is possible to invoke get inside remove like:

public E remove(int index) {
  E elementToRemove = get(index);

  if (size - 1 - index &gt;= 0)
    System.arraycopy(elementData, index + 1, elementData, index, size - 1 - index);

  size--;

  return elementToRemove;
}