1. 程式人生 > >Data Structure - Array List (Java)

Data Structure - Array List (Java)

package chimomo.learning.java.datastructure;

/**
 * @author Created by Chimomo
 */
public class ArrayList<T> implements Iterable<T> {

    private static final int DEFAULT_CAPACITY = 10;
    private T[] items;
    private int size;

    /**
     * Construct an empty array list.
     */
    public ArrayList() {
        clear();
    }

    /**
     * Returns the number of items in this collection.
     *
     * @return The number of items in this collection.
     */
    public int size() {
        return size;
    }

    /**
     * Is array list empty or not.
     *
     * @return True if this collection is empty, false otherwise.
     */
    public boolean isEmpty() {
        return size() == 0;
    }

    /**
     * Gets the item at position idx.
     *
     * @param idx The index to search in.
     * @throws ArrayIndexOutOfBoundsException If index is out of range.
     */
    public T get(int idx) {
        if (idx < 0 || idx >= size()) {
            throw new ArrayIndexOutOfBoundsException("Index " + idx + "; size " + size());
        }
        return items[idx];
    }

    /**
     * Changes the item at position idx.
     *
     * @param idx    The index to change.
     * @param newVal The new value.
     * @return The old value.
     * @throws ArrayIndexOutOfBoundsException If index is out of range.
     */
    public T set(int idx, T newVal) {
        if (idx < 0 || idx >= size()) {
            throw new ArrayIndexOutOfBoundsException("Index " + idx + "; size " + size());
        }
        T old = items[idx];
        items[idx] = newVal;

        return old;
    }

    @SuppressWarnings("unchecked")
    private void ensureCapacity(int newCapacity) {
        if (newCapacity < size) {
            return;
        }

        T[] old = items;
        items = (T[]) new Object[newCapacity];
        for (int i = 0; i < size(); i++) {
            items[i] = old[i];
        }
    }

    /**
     * Adds an item to this collection, at the end.
     *
     * @param x Any object.
     * @return True.
     */
    public boolean add(T x) {
        add(size(), x);
        return true;
    }

    /**
     * Adds an item to this collection, at the specified index.
     *
     * @param x Any object.
     */
    public void add(int idx, T x) {
        if (items.length == size()) {
            ensureCapacity(size() * 2 + 1);
        }

        for (int i = size; i > idx; i--) {
            items[i] = items[i - 1];
        }

        items[idx] = x;
        size++;
    }

    /**
     * Removes an item from this collection.
     *
     * @param idx The index of the object.
     * @return The item was removed from the collection.
     */
    public T remove(int idx) {
        T removedItem = items[idx];

        for (int i = idx; i < size() - 1; i++) {
            items[i] = items[i + 1];
        }
        size--;

        return removedItem;
    }

    /**
     * Clear array list.
     */
    private void clear() {
        size = 0;
        ensureCapacity(DEFAULT_CAPACITY);
    }

    /**
     * Obtains an iterator object used to traverse the collection.
     *
     * @return An iterator positioned prior to the first element.
     */
    public java.util.Iterator<T> iterator() {
        return new ArrayListIterator();
    }

    /**
     * Returns a string representation of this collection.
     */
    public String toString() {
        StringBuilder sb = new StringBuilder("[ ");

        for (T x : this) {
            sb.append(x).append(" ");
        }
        sb.append("]");

        return new String(sb);
    }

    /**
     * This is the implementation of the ArrayListIterator.
     * It maintains a notion of a current position and of course the implicit reference to the ArrayList.
     */
    private class ArrayListIterator implements java.util.Iterator<T> {

        private int current = 0;
        private boolean okToRemove = false;

        public boolean hasNext() {
            return current < size();
        }

        public T next() {
            if (!hasNext()) {
                throw new java.util.NoSuchElementException();
            }

            okToRemove = true;
            return items[current++];
        }

        public void remove() {
            if (!okToRemove) {
                throw new IllegalStateException();
            }

            ArrayList.this.remove(--current);
            okToRemove = false;
        }

    }

    public static void main(String[] args) {
        // Construct an array list.
        ArrayList<Integer> lst = new ArrayList<>();

        // Is empty?
        System.out.println("Is empty? " + lst.isEmpty());

        // Insert.
        for (int i = 0; i < 10; i++) {
            lst.add(i);
        }
        for (int i = 20; i < 30; i++) {
            lst.add(0, i);
        }
        System.out.println("Is empty? " + lst.isEmpty());

        // Remove.
        lst.remove(0);
        lst.remove(lst.size() - 1);
        System.out.println(lst);

        // Iterate.
        java.util.Iterator<Integer> itr = lst.iterator();
        while (itr.hasNext()) {
            itr.next();
            itr.remove();
            System.out.println(lst);
        }
    }

}

/*
Output:
Is empty? true
Is empty? false
[ 28 27 26 25 24 23 22 21 20 0 1 2 3 4 5 6 7 8 ]
[ 27 26 25 24 23 22 21 20 0 1 2 3 4 5 6 7 8 ]
[ 26 25 24 23 22 21 20 0 1 2 3 4 5 6 7 8 ]
[ 25 24 23 22 21 20 0 1 2 3 4 5 6 7 8 ]
[ 24 23 22 21 20 0 1 2 3 4 5 6 7 8 ]
[ 23 22 21 20 0 1 2 3 4 5 6 7 8 ]
[ 22 21 20 0 1 2 3 4 5 6 7 8 ]
[ 21 20 0 1 2 3 4 5 6 7 8 ]
[ 20 0 1 2 3 4 5 6 7 8 ]
[ 0 1 2 3 4 5 6 7 8 ]
[ 1 2 3 4 5 6 7 8 ]
[ 2 3 4 5 6 7 8 ]
[ 3 4 5 6 7 8 ]
[ 4 5 6 7 8 ]
[ 5 6 7 8 ]
[ 6 7 8 ]
[ 7 8 ]
[ 8 ]
[ ]

*/