IntArrayList.java Source code

Java tutorial

Introduction

Here is the source code for IntArrayList.java

Source

/*
 * 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 <tt>ArrayList</tt> avoids the need to "box" each
 * element in an instance of <tt>java.lang.Integer</tt>.
 * It is useful where performance is important.
 *
 * @author <a href="mailto:mmartin5@austin.rr.com">Mike Martin</a>
 * @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 <tt>IntArrayList</tt> 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 <tt>IntArrayList</tt> instance to be the
     * list's current size.
     * An application can use this operation to minimize the storage of an
     * <tt>IntArrayList</tt> 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 <tt>IntArrayList</tt> 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  <tt>true</tt> if this list has no elements;
     *          <tt>false</tt> otherwise.
     */

    public boolean isEmpty() {
        return size == 0;
    }

    /**
     * Returns <tt>true</tt> if this list contains the specified element.
     *
     * @param elem element whose presence in this List is to be tested.
     *
     * @return  <code>true</code> if the specified element is present;
     *          <code>false</code> 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 <tt>-1</tt> 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 <tt>-1</tt> 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 <tt>IntArrayList</tt> instance.
     *
     * @return  A clone of this <tt>ArrayList</tt> 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 <tt>(index &lt; 0 || index &gt;= size())</tt>.
     */

    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 <tt>(index &lt; 0 || index &gt;= size())</tt>.
     */

    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 <tt>(index &lt; 0 || index &gt; size())</tt>.
     */

    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 <tt>(index &lt; 0 || index &gt;= size())</tt>.
     */

    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 <tt>(index &lt; 0 || index &gt; size())</tt>.
     */

    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 <tt>true</tt> if this list contains all of the elements in the
     * specified list.
     * <p>
     * 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 <tt>true</tt> is returned, otherwise
     * <tt>false</tt>.
     *
     * @param ai
     *      Array to be checked for containment in this list.
     *
     * @return
     *      <tt>true</tt> 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.
     * <p>
     * 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
     *      <tt>true</tt> 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.
     * <p>
     * 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
     *      <tt>true</tt> 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 <tt>true</tt> 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 <tt>true</tt> 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 (<tt>"[]"</tt>).
     * Adjacent elements are separated by the characters <tt>", "</tt> (comma
     * and space).
     * Elements are converted to strings as by <tt>String.valueOf(int)</tt>.
     *
     * @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();
    }
}