Collections Data Structure Java

/*
 * Copyright 2004 (C) TJDO.
 * All rights reserved.
 *
 * This software is distributed under the terms of the TJDO License version 1.0.
 * See the terms of the TJDO License in the documentation provided with this software.
 *
 * $Id: IntArrayList.java,v 1.1 2004/01/18 03:01:07 jackknifebarber Exp $
 */
import java.util.Arrays;
/**
 * A variation on the standard ArrayList class that efficiently handles arrays
 * of integers.
 * Using this class rather than ArrayList avoids the need to "box" each
 * element in an instance of java.lang.Integer.
 * It is useful where performance is important.
 *
 * @author Mike Martin
 * @version $Revision: 1.1 $
 */
public class IntArrayList implements Cloneable
{
    private int[] elements;
    private int size = 0;
    /**
     * Constructs an empty list with an initial capacity of ten.
     */
    public IntArrayList()
    {
        this(10);
    }
    /**
     * Constructs an empty list with the specified initial capacity.
     *
     * @param initialCapacity
     *      The initial capacity of the list.
     *
     * @exception IllegalArgumentException
     *      If the specified initial capacity is negative.
     */
    public IntArrayList(int initialCapacity)
    {
        if (initialCapacity < 0)
            throw new IllegalArgumentException("Illegal capacity: "+ initialCapacity);
        elements = new int[initialCapacity];
    }
    /**
     * Constructs a list containing the elements of the specified array.
     * The IntArrayList instance has an initial capacity of 110% the
     * size of the specified collection.
     *
     * @param initialContents
     *      The array whose elements are to be placed into this list.
     */
    public IntArrayList(int[] initialContents)
    {
        size = initialContents.length;
        elements = new int[(int)Math.min((size * 11L)/10, Integer.MAX_VALUE)];
        System.arraycopy(initialContents, 0, elements, 0, size);
    }
    /**
     * Trims the capacity of this IntArrayList instance to be the
     * list's current size.
     * An application can use this operation to minimize the storage of an
     * IntArrayList instance.
     */
    public void trimToSize()
    {
        if (size < elements.length)
        {
            int[] newelems = new int[size];
            System.arraycopy(elements, 0, newelems, 0, size);
            elements = newelems;
        }
    }
    /**
     * Increases the capacity of this IntArrayList instance, if
     * necessary, to ensure that it can hold at least the number of elements
     * specified by the minimum capacity argument.
     *
     * @param minCapacity
     *      The desired minimum capacity.
     */
    public void ensureCapacity(int minCapacity)
    {
        int oldCapacity = elements.length;
        if (minCapacity > oldCapacity)
        {
            int[] newelems = new int[(int)Math.min((oldCapacity * 3L)/2, Integer.MAX_VALUE)];
            System.arraycopy(elements, 0, newelems, 0, size);
            elements = newelems;
        }
    }
    /**
     * Returns the number of elements in this list.
     *
     * @return  The number of elements in this list.
     */
    public int size()
    {
        return size;
    }
    /**
     * Tests if this list has no elements.
     *
     * @return  true if this list has no elements;
     *          false otherwise.
     */
    public boolean isEmpty()
    {
        return size == 0;
    }
    /**
     * Returns true if this list contains the specified element.
     *
     * @param elem element whose presence in this List is to be tested.
     *
     * @return  true if the specified element is present;
     *          false otherwise.
     */
    public boolean contains(int elem)
    {
        return indexOf(elem) >= 0;
    }
    /**
     * Searches for the first occurence of the given argument.
     *
     * @param elem
     *      An integer to search for.
     *
     * @return  The index of the first occurrence of the argument in this
     *          list; returns -1 if the value is not found.
     */
    public int indexOf(int elem)
    {
        for (int i = 0; i < size; ++i)
        {
            if (elements[i] == elem)
                return i;
        }
        return -1;
    }
    /**
     * Returns the index of the last occurrence of the specified integer in
     * this list.
     *
     * @param elem
     *      The desired element.
     *
     * @return  The index of the last occurrence of the specified integer in
     *          this list; returns -1 if the value is not found.
     */
    public int lastIndexOf(int elem)
    {
        for (int i = size - 1; i >= 0; --i)
        {
            if (elements[i] == elem)
                return i;
        }
        return -1;
    }
    /**
     * Returns a copy of this IntArrayList instance.
     *
     * @return  A clone of this ArrayList instance.
     */
    public Object clone()
    {
        try
        {
            IntArrayList l = (IntArrayList)super.clone();
            l.elements = new int[size];
            System.arraycopy(elements, 0, l.elements, 0, size);
            return l;
        }
        catch (CloneNotSupportedException e)
        {
            /* Should never happen since we are Cloneable. */
            throw new InternalError();
        }
    }
    /**
     * Returns an array containing all of the elements in this list.
     *
     * @return An array containing all of the elements in this list.
     */
    public int[] toArray()
    {
        int[] result = new int[size];
        System.arraycopy(elements, 0, result, 0, size);
        return result;
    }
    /**
     * Check if the given index is in range.
     * If not, throw an appropriate runtime exception.
     */
    private void rangeCheck(int index)
    {
        if (index < 0 || index >= size)
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
    }
    /**
     * Returns the element at the specified position in this list.
     *
     * @param index
     *      Index of element to return.
     *
     * @return
     *      The element at the specified position in this list.
     *
     * @exception IndexOutOfBoundsException
     *      If index is out of range (index < 0 || index >= size()).
     */
    public int get(int index)
    {
        rangeCheck(index);
        return elements[index];
    }
    /**
     * Replaces the element at the specified position in this list with
     * the specified element.
     *
     * @param index
     *      Index of element to replace.
     * @param element
     *      Element to be stored at the specified position.
     *
     * @return
     *      The element previously at the specified position.
     *
     * @exception IndexOutOfBoundsException
     *      If index is out of range (index < 0 || index >= size()).
     */
    public int set(int index, int element)
    {
        rangeCheck(index);
        int oldValue = elements[index];
        elements[index] = element;
        return oldValue;
    }
    /**
     * Appends the specified element to the end of this list.
     *
     * @param element
     *      Element to be appended to this list.
     */
    public void add(int element)
    {
        ensureCapacity(size + 1);
        elements[size++] = element;
    }
    /**
     * Inserts the specified element at the specified position in this
     * list.
     * Shifts the element currently at that position (if any) and any subsequent
     * elements to the right (adds one to their indices).
     *
     * @param index
     *      Index at which the specified element is to be inserted.
     * @param element
     *      Element to be inserted.
     *
     * @exception IndexOutOfBoundsException
     *      If index is out of range (index < 0 || index > size()).
     */
    public void add(int index, int element)
    {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        ensureCapacity(size + 1);
        System.arraycopy(elements, index, elements, index + 1, size - index);
        elements[index] = element;
        ++size;
    }
    /**
     * Removes the element at the specified position in this list.
     * Shifts any subsequent elements to the left (subtracts one from their
     * indices).
     *
     * @param index
     *      The index of the element to removed.
     *
     * @return
     *      The element that was removed from the list.
     *
     * @exception IndexOutOfBoundsException
     *      If index is out of range (index < 0 || index >= size()).
     */
    public int remove(int index)
    {
        rangeCheck(index);
        int oldValue = elements[index];
        int numMoved = size - index - 1;
        if (numMoved > 0)
            System.arraycopy(elements, index + 1, elements, index, numMoved);
        --size;
        return oldValue;
    }
    /**
     * Removes all of the elements from this list.
     * The list will be empty after this call returns.
     */
    public void clear()
    {
        size = 0;
    }
    /**
     * Appends all of the elements in the specified array to the end of this
     * list.
     *
     * @param ai
     *      The elements to be added to this list.
     */
    public void addAll(int[] ai)
    {
        int numNew = ai.length;
        ensureCapacity(size + numNew);
        System.arraycopy(ai, 0, elements, size, numNew);
    }
    /**
     * Inserts all of the elements in the specified array into this list,
     * starting at the specified position.
     * Shifts the element currently at that position (if any) and any subsequent
     * elements to the right (increases their indices).
     * The new elements will appear in the list in the order that they exist in
     * the array argument.
     *
     * @param index
     *      Index at which to insert first element from the specified array.
     * @param ai
     *      Elements to be inserted into this list.
     *
     * @exception IndexOutOfBoundsException
     *      If index is out of range (index < 0 || index > size()).
     */
    public void addAll(int index, int[] ai)
    {
        if (index < 0 || index > size)
            throw new IndexOutOfBoundsException("Index: " + index + ", Size: " + size);
        int numNew = ai.length;
        ensureCapacity(size + numNew);
        int numMoved = size - index;
        if (numMoved > 0)
            System.arraycopy(elements, index, elements, index + numNew, numMoved);
        System.arraycopy(ai, 0, elements, index, numNew);
        size += numNew;
    }
    /**
     * Returns true if this list contains all of the elements in the
     * specified list.
     * 


     * This implementation iterates over the specified array, checking each
     * element in turn to see if it's contained in this list.
     * If all elements are so contained true is returned, otherwise
     * false.
     *
     * @param ai
     *      Array to be checked for containment in this list.
     *
     * @return
     *      true if this list contains all of the elements in the
     *      specified array.
     *
     * @see #contains
     */
    public boolean containsAll(int[] ai)
    {
        for (int i = 0; i < ai.length; ++i)
        {
            if (!contains(ai[i]))
                return false;
        }
        return true;
    }
    /**
     * Removes from this list all of its elements that are contained in the
     * specified array.
     * 


     * This implementation iterates over this list, checking each element in
     * turn to see if it's contained in the specified array.
     * If it's so contained, it's removed from this list.
     *
     * @param ai
     *      Elements to be removed from this list.
     *
     * @return
     *      true if this list changed as a result of the call.
     *
     * @see #remove
     * @see #contains
     */
    public boolean removeAll(int[] ai)
    {
        IntArrayList l = new IntArrayList(ai);
        boolean modified = false;
        for (int i = 0; i < size; ++i)
        {
            while (i < size && l.contains(elements[i]))
            {
                remove(i);
                modified = true;
            }
        }
        return modified;
    }
    /**
     * Retains only the elements in this list that are contained in the
     * specified array.
     * In other words, removes from this list all of its elements that are not
     * contained in the specified array.
     * 


     * This implementation iterates over this list, checking each element in
     * turn to see if it's contained in the specified array.
     * If it's not so contained, it's removed from this list.
     *
     * @param ai
     *      Elements to be retained in this list.
     *
     * @return
     *      true if this list changed as a result of the call.
     *
     * @see #remove
     * @see #contains
     */
    public boolean retainAll(int[] ai)
    {
        IntArrayList l = new IntArrayList(ai);
        boolean modified = false;
        for (int i = 0; i < size; ++i)
        {
            while (i < size && !l.contains(elements[i]))
            {
                remove(i);
                modified = true;
            }
        }
        return modified;
    }
    /**
     * Compares the specified object with this list for equality.
     * Returns true if and only if the specified object is also an
     * IntArrayList, both lists have the same size, and all corresponding pairs
     * of elements in the two lists are equal.
     *
     * @param o the object to be compared for equality with this list.
     *
     * @return true if the specified object is equal to this list.
     */
    public boolean equals(Object o)
    {
        if (o == this)
            return true;
        if (!(o instanceof IntArrayList))
            return false;
        return Arrays.equals(toArray(), ((IntArrayList)o).toArray());
    }
    /**
     * Returns the hash code value for this list.
     *
     * @return The hash code value for this list.
     */
    public int hashCode()
    {
        int hashCode = 1;
        for (int i = 0; i < size; ++i)
            hashCode = 31 * hashCode + elements[i];
        return hashCode;
    }
    /**
     * Returns a string representation of this list.
     * The string representation consists of a list of the elements, enclosed
     * in square brackets ("[]").
     * Adjacent elements are separated by the characters ", " (comma
     * and space).
     * Elements are converted to strings as by String.valueOf(int).
     *
     * @return
     *      A string representation of this collection.
     */
    public String toString()
    {
        StringBuffer buf = new StringBuffer();
        buf.append('[');
        for (int i = 0; i < size; ++i)
        {
            if (i > 0)
                buf.append(", ");
            buf.append(elements[i]);
        }
        buf.append(']');
        return buf.toString();
    }
}