home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 1995 November / PCWK1195.iso / inne / win95 / sieciowe / hotja32.lzh / hotjava / classsrc / java / util / vector.java < prev   
Text File  |  1995-08-11  |  12KB  |  403 lines

  1. /*
  2.  * @(#)Vector.java    1.19 95/02/11  
  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.19, 11 Feb 1995
  36.  * @author    Jonathan Payne
  37.  * @author    Lee Boynton
  38.  */
  39. public
  40. class Vector {
  41.     /**
  42.      * The buffer.
  43.      */
  44.     protected Object elementData[];
  45.  
  46.     /**
  47.      * The number of elements.
  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 a vector with zero elements and the specified storage capacity
  59.      * and the specified capacityIncrement.
  60.      */
  61.     public Vector(int initialCapacity, int capacityIncrement) {
  62.     super();
  63.     this.elementData = new Object[initialCapacity];
  64.     this.capacityIncrement = capacityIncrement;
  65.     }
  66.  
  67.     /**
  68.      * Constructs an empty vector with the specified storage capacity.
  69.      */
  70.     public Vector(int initialCapacity) {
  71.     this(initialCapacity, 0);
  72.     }
  73.  
  74.     /**
  75.      * Construct an empty vector.
  76.      */
  77.     public Vector() {
  78.     this(10);
  79.     }
  80.  
  81.  
  82.     /**
  83.      * Copies the elements of this vector into the specified array.
  84.      */
  85.     public final synchronized void copyInto(Object anArray[]) {
  86.     int i = elementCount;
  87.     while (i-- > 0) {
  88.         anArray[i] = elementData[i];
  89.     }
  90.     }
  91.  
  92.     /**
  93.      * Trims the vector's capacity down to size. Use this operation to
  94.      * minimize the storage of a vector. Subsequent insertions will
  95.      * cause reallocation.
  96.      */
  97.     public final synchronized void trimToSize() {
  98.     int oldCapacity = elementData.length;
  99.     if (elementCount < oldCapacity) {
  100.         Object oldData[] = elementData;
  101.         elementData = new Object[elementCount];
  102.         System.arraycopy(oldData, 0, elementData, 0, elementCount);
  103.     }
  104.     }
  105.  
  106.     /**
  107.      * Ensures that the vector has at least the specified capacity.
  108.      * @param minCapacity the desired minimum capacity
  109.      */
  110.     public final synchronized void ensureCapacity(int minCapacity) {
  111.     int oldCapacity = elementData.length;
  112.     if (minCapacity > oldCapacity) {
  113.         Object oldData[] = elementData;
  114.         int newCapacity = (capacityIncrement > 0) ?
  115.         (oldCapacity + capacityIncrement) : (oldCapacity * 2);
  116.             if (newCapacity < minCapacity) {
  117.         newCapacity = minCapacity;
  118.         }
  119.         elementData = new Object[newCapacity];
  120.         System.arraycopy(oldData, 0, elementData, 0, elementCount);
  121.     }
  122.     }
  123.  
  124.     /**
  125.      * Sets the size of the vector. If the size shrinks, the extra elements
  126.      * (at the end of the vector) are lost; if the size increases, the
  127.      * new elements are set to null.
  128.      */
  129.     public final synchronized void setSize(int newSize) {
  130.     if (newSize > elementCount) {
  131.         ensureCapacity(newSize);
  132.     } else {
  133.         for (int i = newSize ; i < elementCount ; i++) {
  134.         elementData[i] = null;
  135.         }
  136.     }
  137.     elementCount = newSize;
  138.     }
  139.  
  140.     /**
  141.      * Returns the current capacity of the vector.
  142.      */
  143.     public final int capacity() {
  144.     return elementData.length;
  145.     }
  146.  
  147.     /**
  148.      * Returns the number of elements in the vector.
  149.      * Note that this is not the same as the vector's capacity.
  150.      */
  151.     public final int size() {
  152.     return elementCount;
  153.     }
  154.  
  155.     /**
  156.      * Returns true if the collection contains no values.
  157.      */
  158.     public final boolean isEmpty() {
  159.     return elementCount == 0;
  160.     }
  161.  
  162.     /**
  163.      * Returns an enumeration of the elements. Use the Enumeration methods on
  164.      * the returned object to fetch the elements sequentially.
  165.      */
  166.     public final synchronized Enumeration elements() {
  167.     return new VectorEnumerator(this);
  168.     }
  169.     
  170.     /**
  171.      * Returns true if the specified object a a value of the collection.
  172.      */
  173.     public final boolean contains(Object elem) {
  174.     return indexOf(elem, 0) >= 0;
  175.     }
  176.  
  177.     /**
  178.      * Searches for the specified object, starting from the first position
  179.      * and returns an index to it.
  180.      * @param elem the desired element
  181.      * @return the index of the element, or -1 if it was not found
  182.      */
  183.     public final int indexOf(Object elem) {
  184.     return indexOf(elem, 0);
  185.     }
  186.  
  187.     /**
  188.      * Searches for the specified object, starting from the specified position
  189.      * and return an index to it.
  190.      * @param elem the desired element
  191.      * @param index the index where to start searching
  192.      * @return the index of the element, or -1 if it was not found
  193.      */
  194.     public final synchronized int indexOf(Object elem, int index) {
  195.     for (int i = index ; i < elementCount ; i++) {
  196.         if (elem.equals(elementData[i])) {
  197.         return i;
  198.         }
  199.     }
  200.     return -1;
  201.     }
  202.  
  203.     /**
  204.      * Searches backwards for the specified object, starting from the last
  205.      * position and returns an index to it. 
  206.      * @param elem the desired element
  207.      * @return the index of the element, or -1 if it was not found
  208.      */
  209.     public final int lastIndexOf(Object elem) {
  210.     return lastIndexOf(elem, elementCount);
  211.     }
  212.  
  213.     /**
  214.      * Searches backwards for the specified object, starting from the specified
  215.      * position and returns an index to it. 
  216.      * @param elem the desired element
  217.      * @param index the index where to start searching
  218.      * @return the index of the element, or -1 if it was not found
  219.      */
  220.     public final synchronized int lastIndexOf(Object elem, int index) {
  221.     for (int i = index ; --i >= 0 ; ) {
  222.         if (elem.equals(elementData[i])) {
  223.         return i;
  224.         }
  225.     }
  226.     return -1;
  227.     }
  228.  
  229.     /**
  230.      * Returns the element at the specified index.
  231.      * @param index the index of the desired element
  232.      * @return the desired element
  233.      * @exception ArrayIndexOutOfBoundsException Invalid index
  234.      */
  235.     public final synchronized Object elementAt(int index) {
  236.     if (index >= elementCount) {
  237.         throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
  238.     }
  239.     /* Since try/catch is free, except when the exception is thrown,
  240.        put in this extra try/catch to catch negative indexes and
  241.        display a more informative error message.  This might not
  242.        be appropriate, especially if we have a decent debugging
  243.        environment - JP. */
  244.     try {
  245.         return elementData[index];
  246.     } catch (ArrayIndexOutOfBoundsException e) {
  247.         throw new ArrayIndexOutOfBoundsException(index + " < 0");
  248.     }
  249.     }
  250.  
  251.     /**
  252.      * Returns the first element of the sequence.
  253.      * @exception NoSuchElementException The sequence is empty.
  254.      */
  255.     public final synchronized Object firstElement() {
  256.     if (elementCount == 0) {
  257.         throw new NoSuchElementException();
  258.     }
  259.     return elementData[0];
  260.     }
  261.  
  262.     /**
  263.      * Returns the last element of the sequence.
  264.      * @exception NoSuchElementException The sequence is empty.
  265.      */
  266.     public final synchronized Object lastElement() {
  267.     if (elementCount == 0) {
  268.         throw new NoSuchElementException();
  269.     }
  270.     return elementData[elementCount - 1];
  271.     }
  272.  
  273.     /**
  274.      * Sets the element at the specified index to be the specified object.
  275.      * The previous element at that position is discarded.
  276.      * @exception ArrayIndexOutOfBoundsException Invalid index
  277.      */
  278.     public final synchronized void setElementAt(Object obj, int index) {
  279.     elementData[index] = obj;
  280.     }
  281.  
  282.     /**
  283.      * Deletes the element at the specified index. Elements with an index
  284.      * greater than index are moved down.
  285.      * @param index the element to remove
  286.      * @exception ArrayIndexOutOfBoundsException Invalid index
  287.      */
  288.     public final synchronized void removeElementAt(int index) {
  289.     if (elementCount > 0) {
  290.         int j = elementCount - index - 1;
  291.         if (j > 0) {
  292.         System.arraycopy(elementData, index + 1, elementData, index, j);
  293.         }
  294.         elementCount--;
  295.         elementData[elementCount] = null; /* to let gc do its work */
  296.     }
  297.     }
  298.  
  299.     /**
  300.      * Inserts the specified object as an element at the specified index.
  301.      * Elements with an index greater or equal to the index are shifted up.
  302.      * @param obj the element to insert
  303.      * @param index where to insert the new element
  304.      * @exception ArrayIndexOutOfBoundsException invalid index
  305.      */
  306.     public final synchronized void insertElementAt(Object obj, int index) {
  307.     ensureCapacity(elementCount + 1);
  308.     System.arraycopy(elementData, index, elementData, index + 1, elementCount - index);
  309.     elementData[index] = obj;
  310.     elementCount++;
  311.     }
  312.  
  313.     /**
  314.      * Adds the specified object as the last element of the vector.
  315.      * @param obj the element to be added
  316.      */
  317.     public final synchronized void addElement(Object obj) {
  318.     ensureCapacity(elementCount + 1);
  319.     elementData[elementCount++] = obj;
  320.     }
  321.  
  322.     /**
  323.      * Removes the element from the vector. If the object occurs more
  324.      * than once, only the first is removed. If the object is not an
  325.      * element, returns false.
  326.      * @param obj the element to be removed
  327.      * @return true if the element was actually removed
  328.      */
  329.     public final synchronized boolean removeElement(Object obj) {
  330.     int i = indexOf(obj);
  331.     if (i >= 0) {
  332.         removeElementAt(i);
  333.         return true;
  334.     }
  335.     return false;
  336.     }
  337.  
  338.     /**
  339.      * Removes all elements of the vector. The vector becomes empty.
  340.      */
  341.     public final synchronized void removeAllElements() {
  342.     for (int i = 0; i < elementCount; i++) {
  343.         elementData[i] = null;
  344.     }
  345.     elementCount = 0;
  346.     }
  347.  
  348.     /**
  349.      * Clone this vector. The elements are not cloned.
  350.      */
  351.     public synchronized Object clone() {
  352.     Vector v = (Vector)super.clone();
  353.     v.elementData = new Object[elementCount];
  354.     System.arraycopy(elementData, 0, v.elementData, 0, elementCount);
  355.     return v;
  356.     }
  357.  
  358.     /**
  359.      * Converts the vector to a string. Useful for debugging.
  360.      */
  361.     public final synchronized String toString() {
  362.     int max = size() - 1;
  363.     StringBuffer buf = new StringBuffer();
  364.     Enumeration e = elements();
  365.     buf.append("[");
  366.  
  367.     for (int i = 0 ; i <= max ; i++) {
  368.         String s = e.nextElement().toString();
  369.         buf.append(s);
  370.         if (i < max) {
  371.         buf.append(", ");
  372.         }
  373.     }
  374.     buf.append("]");
  375.     return buf.toString();
  376.     }
  377. }
  378.  
  379. final
  380. class VectorEnumerator implements Enumeration {
  381.     Vector vector;
  382.     int count;
  383.  
  384.     VectorEnumerator(Vector v) {
  385.     vector = v;
  386.     count = 0;
  387.     }
  388.  
  389.     public boolean hasMoreElements() {
  390.     return count < vector.elementCount;
  391.     }
  392.  
  393.     public Object nextElement() {
  394.     synchronize (vector) {
  395.         if (count < vector.elementCount) {
  396.         return vector.elementData[count++];
  397.         }
  398.     }
  399.     throw new NoSuchElementException("VectorEnumerator");
  400.     }
  401.  
  402. }
  403.