package collection.concrete; import java.util.Arrays; import java.util.NoSuchElementException; import collection.AbstractList; import collection.Iterator; public class ArrayList<E> extends AbstractList<E> { private E[] elements; private int size; private static final int INITIAL_SIZE = 16; public ArrayList() { elements = (E[]) new Object[INITIAL_SIZE]; size = 0; } @Override public void add(E e) { checkCapacity(); elements[size++] = e; } private void checkCapacity() { if (size >= MAX_SIZE) throw new IndexOutOfBoundsException("Reached max size"); if (elements.length - size < INITIAL_SIZE) grow(); } synchronized private void grow() { int newCapacity = size * 2; newCapacity = (newCapacity < 0 || newCapacity - MAX_SIZE > 0) ? MAX_SIZE : newCapacity; E[] target = (E[]) new Object[newCapacity]; System.arraycopy(elements, 0, target, 0, size); elements = target; } public void add(int index, E e) { checkCapacity(); if (index == size) { add(e); return; } checkIndex(index); synchronized (this) { System.arraycopy(elements, index, elements, index + 1, size - index + 1); elements[index] = e; size++; } } @Override public E get(int index) { checkIndex(index); return elements[index]; } public E getLast() { return get(size - 1); } public void addLast(E e) { add(e); } public E removeLast() { checkIndex(size); return elements[--size]; } public E remove(int index) { checkIndex(index); E result = elements[index]; synchronized (this) { System.arraycopy(elements, index + 1, elements, index, size - index - 1); elements[--size] = null; } return result; } @Override public int size() { return size; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + Arrays.hashCode(elements); result = prime * result + size; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; ArrayList other = (ArrayList) obj; if (!Arrays.equals(elements, other.elements)) return false; if (size != other.size) return false; return true; } @Override public Iterator<E> iterator() { return new ArrayListIterator<E>(this); } private class ArrayListIterator<E> implements Iterator<E> { private ArrayList<E> myArrayList; private int pos; public ArrayListIterator(ArrayList<E> arrayList) { myArrayList = arrayList; pos = 0; } @Override public boolean hasNext() { return pos < size; } @Override public E next() { if (hasNext()) return (E) elements[pos++]; throw new NoSuchElementException(); } } }