import java.util.*;
/*
 * Modificacion de ArrayList para ver que una clase Serializable
 * puede implementar sus propios metodo de serializar/des-serializar.
 * Normalmente no se hace.
 */
public class ZArrayList<E> extends AbstractList<E>
         implements java.io.Serializable {
    transient Object[] elementData;
    private int size;
    private static final Object[] EMPTY_ELEMENTDATA = {};
    public ZArrayList(int initialCapacity) {
        if (initialCapacity > 0) {
            this.elementData = new Object[initialCapacity];
            size = 0;
        } else {
            throw new IllegalArgumentException("Illegal Capacity: "+
                                               initialCapacity);
        }
    }
    /* Si. Puedes tener un metodo con el mismo nombre que un atributo. */
    E elementData(int index) {
         return (E) elementData[index];
    }
    @Override
    public int size() {
        return this.size;
    }
    @Override
    public E get(int index) {
        // rangeCheck(index);
        return elementData(index);
    }
    @Override
    public E set(int index, E e) {
        E oldValue = (E) this.elementData[index];
        this.elementData[index] = e;
        return oldValue;
    }
    @Override
    public boolean add(E e) {
        set(this.size, e);
        this.size++;
        return true;
    }
/*
Save the state of the ArrayList instance to a stream (that is, serialize it).
SerialData: The length of the array backing the ArrayList instance is emitted
(int), followed by all of its elements (each an Object) in the proper order.
*/
    private void writeObject(java.io.ObjectOutputStream s)
        throws java.io.IOException{
        int expectedModCount = modCount;
        // Write out element count, and any hidden stuff
        s.defaultWriteObject();
        // Write out all elements in the proper order.
        for (int i=0; i<size; i++) {
            s.writeObject(elementData[i]);
        }
        if (modCount != expectedModCount) {
            throw new ConcurrentModificationException();
        }
    }
/*
Reconstitute the ArrayList instance from a stream (that is, deserialize it).
*/
    private void readObject(java.io.ObjectInputStream s)
        throws java.io.IOException, ClassNotFoundException {
        elementData = EMPTY_ELEMENTDATA;
        // Read in size, and any hidden stuff
        s.defaultReadObject();
        if (size > 0) {
            this.elementData = new Object[size];
            // Read in all elements in the proper order.
            for (int i=0; i<size; i++) {
                this.elementData[i] = s.readObject();
            }
        }
    }
}
