diff options
Diffstat (limited to 'libjava/java/util/ArrayList.java')
-rw-r--r-- | libjava/java/util/ArrayList.java | 497 |
1 files changed, 497 insertions, 0 deletions
diff --git a/libjava/java/util/ArrayList.java b/libjava/java/util/ArrayList.java new file mode 100644 index 0000000..7e6562c --- /dev/null +++ b/libjava/java/util/ArrayList.java @@ -0,0 +1,497 @@ +/* ArrayList.java -- JDK1.2's answer to Vector; this is an array-backed + implementation of the List interface + Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + +This file is part of GNU Classpath. + +GNU Classpath is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +GNU Classpath is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GNU Classpath; see the file COPYING. If not, write to the +Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +02111-1307 USA. + +As a special exception, if you link this library with other files to +produce an executable, this library does not by itself cause the +resulting executable to be covered by the GNU General Public License. +This exception does not however invalidate any other reasons why the +executable file might be covered by the GNU General Public License. */ + + +package java.util; + +import java.lang.reflect.Array; +import java.io.Serializable; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; + +/** + * An array-backed implementation of the List interface. ArrayList + * performs well on simple tasks: random access into a list, appending + * to or removing from the end of a list, checking the size, &c. + * + * @author Jon A. Zeppieri + * @version $Id: ArrayList.java,v 1.4 2000/03/15 21:59:06 rao Exp $ + * @see java.util.AbstractList + * @see java.util.List + */ +public class ArrayList extends AbstractList + implements List, Cloneable, Serializable +{ + /** the default capacity for new ArrayLists */ + private static final int DEFAULT_CAPACITY = 16; + + /** the number of elements in this list */ + int _iSize; + + /** where the data is stored */ + Object[] _arData; + + /** used for serialization -- denotes which fields are serialized */ + private static final ObjectStreamField[] serialPersistentFields = + {new ObjectStreamField("size", int.class)}; + + /** + * Construct a new ArrayList with the supplied initial capacity. + * + * @param iCapacity + */ + public ArrayList(int iCapacity) + { + _arData = new Object[iCapacity]; + } + + + /** + * Construct a new ArrayList with the default capcity + */ + public ArrayList() + { + this(DEFAULT_CAPACITY); + } + + /** + * Construct a new ArrayList, and initialize it with the elements + * in the supplied Collection; Sun specs say that the initial + * capacity is 110% of the Collection's size. + * + * @param oCollection the collection whose elements will + * initialize this list + */ + public ArrayList(Collection oCollection) + { + this((int) (oCollection.size() * 1.1)); + addAll(oCollection); + } + + /** + * Guarantees that this list will have at least enough capacity to + * hold iMinCapacity elements. + * + * @param iMinCapacity the minimum guaranteed capacity + */ + public void ensureCapacity(int iMinCapacity) + { + Object[] arNewData; + int iCapacity = _arData.length; + + if (iMinCapacity > iCapacity) + { + arNewData = new Object[Math.max((iCapacity * 2), iMinCapacity)]; + System.arraycopy(_arData, 0, arNewData, 0, iCapacity); + _arData = arNewData; + } + } + + /** + * Appends the supplied element to the end of this list. + * + * @param oElement the element to be appended to this list + */ + public boolean add(Object oElement) + { + ensureCapacity(_iSize + 1); + _arData[_iSize++] = oElement; + modCount++; + return true; + } + + /** + * Retrieves the element at the user-supplied index. + * + * @param iIndex the index of the element we are fetching + * @throws IndexOutOfBoundsException (iIndex < 0) || (iIndex >= size()) + */ + public Object get(int iIndex) + { + if (iIndex >= _iSize) + throw new IndexOutOfBoundsException("ArrayList size=" + + String.valueOf(_iSize) + "; " + + "index=" + String.valueOf(iIndex)); + return _arData[iIndex]; + } + + /** + * Returns the number of elements in this list + */ + public int size() + { + return _iSize; + } + + /** + * Removes the element at the user-supplied index + * + * @param iIndex the index of the element to be removed + * @return the removed Object + * @throws IndexOutOfBoundsException (iIndex < 0) || (iIndex >= size()) + */ + public Object remove(int iIndex) + { + Object oResult; + + if (iIndex >= _iSize) + throw new IndexOutOfBoundsException("ArrayList size=" + + String.valueOf(_iSize) + "; " + + "index=" + String.valueOf(iIndex)); + + oResult = _arData[iIndex]; + + if (iIndex != --_iSize) + System.arraycopy(_arData, (iIndex + 1), _arData, iIndex, + (_iSize - iIndex)); + + modCount++; + _arData[_iSize] = null; + + return oResult; + } + + /** + * Removes all elements in the half-open interval [iFromIndex, iToIndex). + * + * @param iFromIndex the first index which will be removed + * @param iToIndex one greater than the last index which will be + * removed + */ + public void removeRange(int iFromIndex, int iToIndex) + { + int iReduction; + int i; + + if ((iFromIndex >= _iSize) || (iToIndex >= _iSize)) + { + throw new IndexOutOfBoundsException("ArrayList size=" + + String.valueOf(_iSize) + "; " + + "indices=" + + String.valueOf(iFromIndex) + "," + + String.valueOf(iToIndex)); + } + else if (iFromIndex > iToIndex) + { + throw new IllegalArgumentException("fromIndex(" + + String.valueOf(iFromIndex) + + ") > toIndex(" + + String.valueOf(iToIndex) + ")"); + } + else if (iFromIndex != iToIndex) + { + iReduction = iToIndex - iFromIndex; + System.arraycopy(_arData, (iFromIndex + iReduction), _arData, + iFromIndex, (_iSize - iFromIndex - iReduction)); + modCount++; + + for (i = (iFromIndex + iReduction); i < _iSize; i++) + _arData[i] = null; + + _iSize -= iReduction; + } + } + + /** + * Adds the supplied element at the specified index, shifting all + * elements currently at that index or higher one to the right. + * + * @param iIndex the index at which the element is being added + * @param oElement the element being added + */ + public void add(int iIndex, Object oElement) + { + if (iIndex > _iSize) + throw new IndexOutOfBoundsException("ArrayList size=" + + String.valueOf(_iSize) + "; " + + "index=" + String.valueOf(iIndex)); + + ensureCapacity(_iSize + 1); + System.arraycopy(_arData, iIndex, _arData, + (iIndex + 1), (_iSize - iIndex)); + _arData[iIndex] = oElement; + _iSize++; + modCount++; + } + + /** + * Add each element in the supplied Collection to this List. + * + * @param oCollection a Collection containing elements to be + * added to this List + */ + public boolean addAll(Collection oCollection) + { + Iterator itElements; + int iLen = oCollection.size(); + + if (iLen > 0) + { + ensureCapacity(_iSize + iLen); + modCount++; + + itElements = oCollection.iterator(); + + while (itElements.hasNext()) + _arData[_iSize++] = itElements.next(); + + return true; + } + return false; + } + + /** + * Add all elements in the supplied collection, inserting them beginning + * at the specified index. + * + * @param iIndex the index at which the elements will be inserted + * @param oCollection the Collection containing the elements to be + * inserted + */ + public boolean addAll(int iIndex, Collection oCollection) + { + Iterator itElements; + int iLen; + + if (iIndex > _iSize) + throw new IndexOutOfBoundsException("ArrayList size=" + + String.valueOf(_iSize) + "; " + + "index=" + String.valueOf(iIndex)); + + iLen = oCollection.size(); + + if (iLen > 0) + { + ensureCapacity(_iSize + iLen); + + System.arraycopy(_arData, iIndex, _arData, + (iIndex + iLen), (_iSize - iIndex)); + modCount++; + _iSize += iLen; + + itElements = oCollection.iterator(); + while (itElements.hasNext()) + _arData[iIndex++] = itElements.next(); + + return true; + } + return false; + } + + /** + * Creates a shallow copy of this ArrayList + */ + public Object clone() + { + ArrayList oClone; + + try + { + oClone = (ArrayList) super.clone(); + oClone._arData = _arData; + oClone._iSize = _iSize; + } + catch(CloneNotSupportedException e) + { + oClone = null; + } + return oClone; + } + + /** + * Returns true iff oElement is in this ArrayList. + * + * @param oElement the element whose inclusion in the List is being + * tested + */ + public boolean contains(Object oElement) + { + return (indexOf(oElement) != -1); + } + + /** + * Returns the lowest index at which oElement appears in this List, or + * -1 if it does not appear. + * + * @param oElement the element whose inclusion in the List is being + * tested + */ + public int indexOf(Object oElement) + { + int i; + + for (i = 0; i < _iSize; i++) + { + if (doesEqual(oElement, _arData[i])) + return i; + } + return -1; + } + + /** + * Returns the highest index at which oElement appears in this List, or + * -1 if it does not appear. + * + * @param oElement the element whose inclusion in the List is being + * tested + */ + public int lastIndexOf(Object oElement) + { + int i; + + for (i = _iSize - 1; i >= 0; i--) + { + if (doesEqual(oElement, _arData[i])) + return i; + } + return -1; + } + + /** + * Removes all elements from this List + */ + public void clear() + { + int i; + + if (_iSize > 0) + { + modCount++; + _iSize = 0; + + for (i = 0; i < _iSize; i++) + _arData[i] = null; + } + } + + /** + * Sets the element at the specified index. + * + * @param iIndex the index at which the element is being set + * @param oElement the element to be set + * @return the element previously at the specified index, or null if + * none was there + */ + public Object set(int iIndex, Object oElement) + { + Object oResult; + + if (iIndex >= _iSize) + throw new IndexOutOfBoundsException("ArrayList size=" + + String.valueOf(_iSize) + "; " + + "index=" + String.valueOf(iIndex)); + oResult = _arData[iIndex]; + // SEH: no structural change, so don't update modCount + _arData[iIndex] = oElement; + + return oResult; + } + + /** + * Returns an Object Array containing all of the elements in this ArrayList + */ + public Object[] toArray() + { + Object[] arObjects = new Object[_iSize]; + System.arraycopy(_arData, 0, arObjects, 0, _iSize); + return arObjects; + } + + /** + * Returns an Array whse component type is the runtime component type of + * the passes-in Array. The returned Array is populated with all of the + * elements in this ArrayList. If the passed-in Array is not large enough + * to store all of the elements in this List, a new Array will be created + * and returned; if the passed-in Array is <i>larger</i> than the size + * of this List, then size() + 1 index will be set to null. + * + * @param arObjects the passed-in Array + */ + public Object[] toArray(Object[] arObjects) + { + Object[] arReturn = (arObjects.length >= _iSize) + ? arObjects + : (Object[]) + Array.newInstance(arObjects.getClass().getComponentType(), _iSize); + + System.arraycopy(_arData, 0, arReturn, 0, _iSize); + + if (arReturn.length > _iSize) + arReturn[_iSize] = null; + + return arReturn; + } + + /** + * Trims the capacity of tjis List to be equal to its size; + * a memory saver. + */ + public void trimToSize() + { + Object[] arNewData = new Object[_iSize]; + System.arraycopy(_arData, 0, arNewData, 0, _iSize); + modCount++; + _arData = arNewData; + } + + private void writeObject(ObjectOutputStream oOut) + throws IOException + { + int i; + + ObjectOutputStream.PutField oFields = oOut.putFields(); + oFields.put("size", _iSize); + oOut.writeFields(); + + oOut.writeInt(_arData.length); + for (i = 0; i < _arData.length; i++) + oOut.writeObject(_arData[i]); + } + + private void readObject(ObjectInputStream oIn) + throws IOException, ClassNotFoundException + { + int i; + int iCapacity; + + ObjectInputStream.GetField oFields = oIn.readFields(); + _iSize = oFields.get("size", 0); + + iCapacity = oIn.readInt(); + _arData = new Object[iCapacity]; + + for (i = 0; i < iCapacity; i++) + _arData[i] = oIn.readObject(); + } + + private static final boolean doesEqual(Object oOne, Object oTwo) + { + return ((oOne == null) ? (oTwo == null) : oOne.equals(oTwo)); + } +} |