home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1997 May / Pcwk0597.iso / sybase / starbuck / java.z / Vector.java < prev    next >
Text File  |  1996-05-03  |  13KB  |  430 lines

  1. /*
  2.  * @(#)Vector.java    1.29 95/12/01  
  3.  *
  4.  * Copyright (c) 1994 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Permission to use, copy, modify, and distribute this software
  7.  * and its documentation for NON-COMMERCIAL purposes and without
  8.  * fee is hereby granted provided that this copyright notice
  9.  * appears in all copies. Please refer to the file "copyright.html"
  10.  * for further important copyright and licensing information.
  11.  *
  12.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  13.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  14.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  15.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  16.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  17.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  18.  */
  19.  
  20. package java.util;
  21.  
  22. /**
  23.  * Vector class (a growable array).<p>
  24.  * 
  25.  * Each vector tries to optimize storage management by maintaining
  26.  * a capacity and a capacityIncrement. The capacity is always at
  27.  * least as large as the vector size; it is usually larger because
  28.  * as elements are added to the vector, the vector's
  29.  * storage increases in chunks the size of capacityIncrement. Setting
  30.  * the capacity to what you want before inserting a large number of
  31.  * objects will reduce the amount of incremental reallocation.
  32.  * You can safely ignore the capacity and the vector will still work
  33.  * correctly.
  34.  *
  35.  * @version     1.29, 01 Dec 1995
  36.  * @author    Jonathan Payne
  37.  * @author    Lee Boynton
  38.  */
  39. public
  40. class Vector implements Cloneable {
  41.     /**
  42.      * The buffer where elements are stored.
  43.      */
  44.     protected Object elementData[];
  45.  
  46.     /**
  47.      * The number of elements in the buffer.
  48.      */
  49.     protected int elementCount;
  50.  
  51.     /**
  52.      * The size of the increment. If it is 0 the size of the
  53.      * the buffer is doubled everytime it needs to grow.
  54.      */
  55.     protected int capacityIncrement;
  56.  
  57.     /**
  58.      * Constructs an empty vector with the specified storage
  59.      * capacity and the specified capacityIncrement.
  60.      * @param initialCapacity the initial storage capacity of the vector
  61.      * @param capacityIncrement how much to increase the element's 
  62.      * size by.
  63.      */
  64.     public Vector(int initialCapacity, int capacityIncrement) {
  65.     super();
  66.     this.elementData = new Object[initialCapacity];
  67.     this.capacityIncrement = capacityIncrement;
  68.     }
  69.  
  70.     /**
  71.      * Constructs an empty vector with the specified storage capacity.
  72.      * @param initialCapacity the initial storage capacity of the vector
  73.      */
  74.     public Vector(int initialCapacity) {
  75.     this(initialCapacity, 0);
  76.     }
  77.  
  78.     /**
  79.      * Constructs an empty vector.
  80.      */
  81.     public Vector() {
  82.     this(10);
  83.     }
  84.  
  85.  
  86.     /**
  87.      * Copies the elements of this vector into the specified array.
  88.      * @param anArray the array where elements get copied into
  89.      */
  90.     public final synchronized void copyInto(Object anArray[]) {
  91.     int i = elementCount;
  92.     while (i-- > 0) {
  93.         anArray[i] = elementData[i];
  94.     }
  95.     }
  96.  
  97.     /**
  98.      * Trims the vector's capacity down to size. Use this operation to
  99.      * minimize the storage of a vector. Subsequent insertions will
  100.      * cause reallocation.
  101.      */
  102.     public final synchronized void trimToSize() {
  103.     int oldCapacity = elementData.length;
  104.     if (elementCount < oldCapacity) {
  105.         Object oldData[] = elementData;
  106.         elementData = new Object[elementCount];
  107.         System.arraycopy(oldData, 0, elementData, 0, elementCount);
  108.     }
  109.     }
  110.  
  111.     /**
  112.      * Ensures that the vector has at least the specified capacity.
  113.      * @param minCapacity the desired minimum capacity
  114.      */
  115.     public final synchronized void ensureCapacity(int minCapacity) {
  116.     int oldCapacity = elementData.length;
  117.     if (minCapacity > oldCapacity) {
  118.         Object oldData[] = elementData;
  119.         int newCapacity = (capacityIncrement > 0) ?
  120.         (oldCapacity + capacityIncrement) : (oldCapacity * 2);
  121.             if (newCapacity < minCapacity) {
  122.         newCapacity = minCapacity;
  123.         }
  124.         elementData = new Object[newCapacity];
  125.         System.arraycopy(oldData, 0, elementData, 0, elementCount);
  126.     }
  127.     }
  128.  
  129.     /**
  130.      * Sets the size of the vector. If the size shrinks, the extra elements
  131.      * (at the end of the vector) are lost; if the size increases, the
  132.      * new elements are set to null.
  133.      * @param newSize the new size of the vector
  134.      */
  135.     public final synchronized void setSize(int newSize) {
  136.     if (newSize > elementCount) {
  137.         ensureCapacity(newSize);
  138.     } else {
  139.         for (int i = newSize ; i < elementCount ; i++) {
  140.         elementData[i] = null;
  141.         }
  142.     }
  143.     elementCount = newSize;
  144.     }
  145.  
  146.     /**
  147.      * Returns the current capacity of the vector.
  148.      */
  149.     public final int capacity() {
  150.     return elementData.length;
  151.     }
  152.  
  153.     /**
  154.      * Returns the number of elements in the vector.
  155.      * Note that this is not the same as the vector's capacity.
  156.      */
  157.     public final int size() {
  158.     return elementCount;
  159.     }
  160.  
  161.     /**
  162.      * Returns true if the collection contains no values.
  163.      */
  164.     public final boolean isEmpty() {
  165.     return elementCount == 0;
  166.     }
  167.  
  168.     /**
  169.      * Returns an enumeration of the elements. Use the Enumeration methods on
  170.      * the returned object to fetch the elements sequentially.
  171.      */
  172.     public final synchronized Enumeration elements() {
  173.     return new VectorEnumerator(this);
  174.     }
  175.     
  176.     /**
  177.      * Returns true if the specified object is a value of the 
  178.      * collection.
  179.      * @param elem the desired element
  180.      */
  181.     public final boolean contains(Object elem) {
  182.     return indexOf(elem, 0) >= 0;
  183.     }
  184.  
  185.     /**
  186.      * Searches for the specified object, starting from the first position
  187.      * and returns an index to it.
  188.      * @param elem the desired element
  189.      * @return the index of the element, or -1 if it was not found.
  190.      */
  191.     public final int indexOf(Object elem) {
  192.     return indexOf(elem, 0);
  193.     }
  194.  
  195.     /**
  196.      * Searches for the specified object, starting at the specified 
  197.      * position and returns an index to it.
  198.      * @param elem the desired element
  199.      * @param index the index where to start searching
  200.      * @return the index of the element, or -1 if it was not found.
  201.      */
  202.     public final synchronized int indexOf(Object elem, int index) {
  203.     for (int i = index ; i < elementCount ; i++) {
  204.         if (elem.equals(elementData[i])) {
  205.         return i;
  206.         }
  207.     }
  208.     return -1;
  209.     }
  210.  
  211.     /**
  212.      * Searches backwards for the specified object, starting from the last
  213.      * position and returns an index to it. 
  214.      * @param elem the desired element
  215.      * @return the index of the element, or -1 if it was not found.
  216.      */
  217.     public final int lastIndexOf(Object elem) {
  218.     return lastIndexOf(elem, elementCount);
  219.     }
  220.  
  221.     /**
  222.      * Searches backwards for the specified object, starting from the specified
  223.      * position and returns an index to it. 
  224.      * @param elem the desired element
  225.      * @param index the index where to start searching
  226.      * @return the index of the element, or -1 if it was not found.
  227.      */
  228.     public final synchronized int lastIndexOf(Object elem, int index) {
  229.     for (int i = index ; --i >= 0 ; ) {
  230.         if (elem.equals(elementData[i])) {
  231.         return i;
  232.         }
  233.     }
  234.     return -1;
  235.     }
  236.  
  237.     /**
  238.      * Returns the element at the specified index.
  239.      * @param index the index of the desired element
  240.      * @exception ArrayIndexOutOfBoundsException If an invalid 
  241.      * index was given.
  242.      */
  243.     public final synchronized Object elementAt(int index) {
  244.     if (index >= elementCount) {
  245.         throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
  246.     }
  247.     /* Since try/catch is free, except when the exception is thrown,
  248.        put in this extra try/catch to catch negative indexes and
  249.        display a more informative error message.  This might not
  250.        be appropriate, especially if we have a decent debugging
  251.        environment - JP. */
  252.     try {
  253.         return elementData[index];
  254.     } catch (ArrayIndexOutOfBoundsException e) {
  255.         throw new ArrayIndexOutOfBoundsException(index + " < 0");
  256.     }
  257.     }
  258.  
  259.     /**
  260.      * Returns the first element of the sequence.
  261.      * @exception NoSuchElementException If the sequence is empty.
  262.      */
  263.     public final synchronized Object firstElement() {
  264.     if (elementCount == 0) {
  265.         throw new NoSuchElementException();
  266.     }
  267.     return elementData[0];
  268.     }
  269.  
  270.     /**
  271.      * Returns the last element of the sequence.
  272.      * @exception NoSuchElementException If the sequence is empty.
  273.      */
  274.     public final synchronized Object lastElement() {
  275.     if (elementCount == 0) {
  276.         throw new NoSuchElementException();
  277.     }
  278.     return elementData[elementCount - 1];
  279.     }
  280.  
  281.     /**
  282.      * Sets the element at the specified index to be the specified object.
  283.      * The previous element at that position is discarded.
  284.      * @param obj what the element is to be set to
  285.      * @param index the specified index
  286.      * @exception ArrayIndexOutOfBoundsException If the index was 
  287.      * invalid.
  288.      */
  289.     public final synchronized void setElementAt(Object obj, int index) {
  290.     if (index >= elementCount) {
  291.         throw new ArrayIndexOutOfBoundsException(index + " >= " + 
  292.                              elementCount);
  293.     }
  294.     elementData[index] = obj;
  295.     }
  296.  
  297.     /**
  298.      * Deletes the element at the specified index. Elements with an index
  299.      * greater than the current index are moved down.
  300.      * @param index the element to remove
  301.      * @exception ArrayIndexOutOfBoundsException If the index was invalid.
  302.      */
  303.     public final synchronized void removeElementAt(int index) {
  304.     if (index >= elementCount) {
  305.         throw new ArrayIndexOutOfBoundsException(index + " >= " + 
  306.                              elementCount);
  307.     }
  308.     int j = elementCount - index - 1;
  309.     if (j > 0) {
  310.         System.arraycopy(elementData, index + 1, elementData, index, j);
  311.     }
  312.     elementCount--;
  313.     elementData[elementCount] = null; /* to let gc do its work */
  314.     }
  315.  
  316.     /**
  317.      * Inserts the specified object as an element at the specified index.
  318.      * Elements with an index greater or equal to the current index 
  319.      * are shifted up.
  320.      * @param obj the element to insert
  321.      * @param index where to insert the new element
  322.      * @exception ArrayIndexOutOfBoundsException If the index was invalid.
  323.      */
  324.     public final synchronized void insertElementAt(Object obj, int index) {
  325.     if (index >= elementCount + 1) {
  326.         throw new ArrayIndexOutOfBoundsException(index + " >= " + 
  327.                              elementCount + 1);
  328.     }
  329.     ensureCapacity(elementCount + 1);
  330.     System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
  331.     elementData[index] = obj;
  332.     elementCount++;
  333.     }
  334.  
  335.     /**
  336.      * Adds the specified object as the last element of the vector.
  337.      * @param obj the element to be added
  338.      */
  339.     public final synchronized void addElement(Object obj) {
  340.     ensureCapacity(elementCount + 1);
  341.     elementData[elementCount++] = obj;
  342.     }
  343.  
  344.     /**
  345.      * Removes the element from the vector. If the object occurs more
  346.      * than once, only the first is removed. If the object is not an
  347.      * element, returns false.
  348.      * @param obj the element to be removed
  349.      * @return true if the element was actually removed; false otherwise.
  350.      */
  351.     public final synchronized boolean removeElement(Object obj) {
  352.     int i = indexOf(obj);
  353.     if (i >= 0) {
  354.         removeElementAt(i);
  355.         return true;
  356.     }
  357.     return false;
  358.     }
  359.  
  360.     /**
  361.      * Removes all elements of the vector. The vector becomes empty.
  362.      */
  363.     public final synchronized void removeAllElements() {
  364.     for (int i = 0; i < elementCount; i++) {
  365.         elementData[i] = null;
  366.     }
  367.     elementCount = 0;
  368.     }
  369.  
  370.     /**
  371.      * Clones this vector. The elements are <strong>not</strong> cloned.
  372.      */
  373.     public synchronized Object clone() {
  374.     try { 
  375.         Vector v = (Vector)super.clone();
  376.         v.elementData = new Object[elementCount];
  377.         System.arraycopy(elementData, 0, v.elementData, 0, elementCount);
  378.         return v;
  379.     } catch (CloneNotSupportedException e) { 
  380.         // this shouldn't happen, since we are Cloneable
  381.         throw new InternalError();
  382.     }
  383.     }
  384.  
  385.     /**
  386.      * Converts the vector to a string. Useful for debugging.
  387.      */
  388.     public final synchronized String toString() {
  389.     int max = size() - 1;
  390.     StringBuffer buf = new StringBuffer();
  391.     Enumeration e = elements();
  392.     buf.append("[");
  393.  
  394.     for (int i = 0 ; i <= max ; i++) {
  395.         String s = e.nextElement().toString();
  396.         buf.append(s);
  397.         if (i < max) {
  398.         buf.append(", ");
  399.         }
  400.     }
  401.     buf.append("]");
  402.     return buf.toString();
  403.     }
  404. }
  405.  
  406. final
  407. class VectorEnumerator implements Enumeration {
  408.     Vector vector;
  409.     int count;
  410.  
  411.     VectorEnumerator(Vector v) {
  412.     vector = v;
  413.     count = 0;
  414.     }
  415.  
  416.     public boolean hasMoreElements() {
  417.     return count < vector.elementCount;
  418.     }
  419.  
  420.     public Object nextElement() {
  421.     synchronized (vector) {
  422.         if (count < vector.elementCount) {
  423.         return vector.elementData[count++];
  424.         }
  425.     }
  426.     throw new NoSuchElementException("VectorEnumerator");
  427.     }
  428.  
  429. }
  430.