Java tutorial
/* * 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 < 0 || index >= 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 < 0 || index >= 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 < 0 || index > 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 < 0 || index >= 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 < 0 || index > 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(); } }