001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package java.util;
028:
029: import com.sun.cldchi.jvm.JVM;
030:
031: /**
032: * The <code>Vector</code> class implements a growable array of
033: * objects. Like an array, it contains components that can be
034: * accessed using an integer index. However, the size of a
035: * <code>Vector</code> can grow or shrink as needed to accommodate
036: * adding and removing items after the <code>Vector</code> has been created.
037: * <p>
038: * Each vector tries to optimize storage management by maintaining a
039: * <code>capacity</code> and a <code>capacityIncrement</code>. The
040: * <code>capacity</code> is always at least as large as the vector
041: * size; it is usually larger because as components are added to the
042: * vector, the vector's storage increases in chunks the size of
043: * <code>capacityIncrement</code>. An application can increase the
044: * capacity of a vector before inserting a large number of
045: * components; this reduces the amount of incremental reallocation.
046: *
047: * @version 12/17/01 (CLDC 1.1)
048: * @since JDK1.0, CLDC 1.0
049: */
050: public class Vector {
051:
052: /**
053: * The array buffer into which the components of the vector are
054: * stored. The capacity of the vector is the length of this array buffer.
055: *
056: * @since JDK1.0
057: */
058: protected Object elementData[];
059:
060: /**
061: * The number of valid components in the vector.
062: *
063: * @since JDK1.0
064: */
065: protected int elementCount;
066:
067: /**
068: * The amount by which the capacity of the vector is automatically
069: * incremented when its size becomes greater than its capacity. If
070: * the capacity increment is <code>0</code>, the capacity of the
071: * vector is doubled each time it needs to grow.
072: *
073: * @since JDK1.0
074: */
075: protected int capacityIncrement;
076:
077: /**
078: * Constructs an empty vector with the specified initial capacity and
079: * capacity increment.
080: *
081: * @param initialCapacity the initial capacity of the vector.
082: * @param capacityIncrement the amount by which the capacity is
083: * increased when the vector overflows.
084: * @exception IllegalArgumentException if the specified initial capacity
085: * is negative
086: */
087: public Vector(int initialCapacity, int capacityIncrement) {
088: super ();
089: if (initialCapacity < 0) {
090: throw new IllegalArgumentException(
091: /* #ifdef VERBOSE_EXCEPTIONS */
092: /// skipped "Illegal Capacity: "+ initialCapacity
093: /* #endif */
094: );
095: }
096: this .elementData = new Object[initialCapacity];
097: this .capacityIncrement = capacityIncrement;
098: }
099:
100: /**
101: * Constructs an empty vector with the specified initial capacity.
102: *
103: * @param initialCapacity the initial capacity of the vector.
104: * @since JDK1.0
105: */
106: public Vector(int initialCapacity) {
107: this (initialCapacity, 0);
108: }
109:
110: /**
111: * Constructs an empty vector.
112: *
113: * @since JDK1.0
114: */
115: public Vector() {
116: this (10);
117: }
118:
119: /**
120: * Copies the components of this vector into the specified array.
121: * The array must be big enough to hold all the objects in this vector.
122: *
123: * @param anArray the array into which the components get copied.
124: * @since JDK1.0
125: */
126: public synchronized void copyInto(Object anArray[]) {
127: int i = elementCount;
128: while (i-- > 0) {
129: anArray[i] = elementData[i];
130: }
131: }
132:
133: /**
134: * Trims the capacity of this vector to be the vector's current
135: * size. An application can use this operation to minimize the
136: * storage of a vector.
137: *
138: * @since JDK1.0
139: */
140: public synchronized void trimToSize() {
141: int oldCapacity = elementData.length;
142: if (elementCount < oldCapacity) {
143: Object oldData[] = elementData;
144: elementData = new Object[elementCount];
145: JVM.unchecked_obj_arraycopy(oldData, 0, elementData, 0,
146: elementCount);
147: }
148: }
149:
150: /**
151: * Increases the capacity of this vector, if necessary, to ensure
152: * that it can hold at least the number of components specified by
153: * the minimum capacity argument.
154: *
155: * @param minCapacity the desired minimum capacity.
156: * @since JDK1.0
157: */
158: public synchronized void ensureCapacity(int minCapacity) {
159: if (minCapacity > elementData.length) {
160: ensureCapacityHelper(minCapacity);
161: }
162: }
163:
164: /**
165: * This implements the unsynchronized semantics of ensureCapacity.
166: * Synchronized methods in this class can internally call this
167: * method for ensuring capacity without incurring the cost of an
168: * extra synchronization.
169: *
170: * @see java.util.Vector#ensureCapacity(int)
171: */
172: private void ensureCapacityHelper(int minCapacity) {
173: int oldCapacity = elementData.length;
174: Object oldData[] = elementData;
175: int newCapacity = (capacityIncrement > 0) ? (oldCapacity + capacityIncrement)
176: : (oldCapacity * 2);
177: if (newCapacity < minCapacity) {
178: newCapacity = minCapacity;
179: }
180: elementData = new Object[newCapacity];
181: JVM.unchecked_obj_arraycopy(oldData, 0, elementData, 0,
182: elementCount);
183: }
184:
185: /**
186: * Sets the size of this vector. If the new size is greater than the
187: * current size, new <code>null</code> items are added to the end of
188: * the vector. If the new size is less than the current size, all
189: * components at index <code>newSize</code> and greater are discarded.
190: *
191: * @param newSize the new size of this vector.
192: * @throws ArrayIndexOutOfBoundsException if new size is negative.
193: * @since JDK1.0
194: */
195: public synchronized void setSize(int newSize) {
196: if ((newSize > elementCount) && (newSize > elementData.length)) {
197: ensureCapacityHelper(newSize);
198: } else {
199: for (int i = newSize; i < elementCount; i++) {
200: elementData[i] = null;
201: }
202: }
203: elementCount = newSize;
204: }
205:
206: /**
207: * Returns the current capacity of this vector.
208: *
209: * @return the current capacity of this vector.
210: * @since JDK1.0
211: */
212: public int capacity() {
213: return elementData.length;
214: }
215:
216: /**
217: * Returns the number of components in this vector.
218: *
219: * @return the number of components in this vector.
220: * @since JDK1.0
221: */
222: public int size() {
223: return elementCount;
224: }
225:
226: /**
227: * Tests if this vector has no components.
228: *
229: * @return <code>true</code> if this vector has no components;
230: * <code>false</code> otherwise.
231: * @since JDK1.0
232: */
233: public boolean isEmpty() {
234: return elementCount == 0;
235: }
236:
237: /**
238: * Returns an enumeration of the components of this vector.
239: *
240: * @return an enumeration of the components of this vector.
241: * @see java.util.Enumeration
242: * @since JDK1.0
243: */
244: public synchronized Enumeration elements() {
245: return new VectorEnumerator(this );
246: }
247:
248: /**
249: * Tests if the specified object is a component in this vector.
250: *
251: * @param elem an object.
252: * @return <code>true</code> if the specified object is a component in
253: * this vector; <code>false</code> otherwise.
254: * @since JDK1.0
255: */
256: public boolean contains(Object elem) {
257: return indexOf(elem, 0) >= 0;
258: }
259:
260: /**
261: * Searches for the first occurrence of the given argument, testing
262: * for equality using the <code>equals</code> method.
263: *
264: * @param elem an object.
265: * @return the index of the first occurrence of the argument in this
266: * vector; returns <code>-1</code> if the object is not found.
267: * @see java.lang.Object#equals(java.lang.Object)
268: * @since JDK1.0
269: */
270: public int indexOf(Object elem) {
271: return indexOf(elem, 0);
272: }
273:
274: /**
275: * Searches for the first occurrence of the given argument, beginning
276: * the search at <code>index</code>, and testing for equality using
277: * the <code>equals</code> method.
278: *
279: * @param elem an object.
280: * @param index the index to start searching from.
281: * @return the index of the first occurrence of the object argument in
282: * this vector at position <code>index</code> or later in the
283: * vector; returns <code>-1</code> if the object is not found.
284: * @see java.lang.Object#equals(java.lang.Object)
285: * @since JDK1.0
286: */
287: public synchronized int indexOf(Object elem, int index) {
288: if (elem == null) {
289: for (int i = index; i < elementCount; i++)
290: if (elementData[i] == null)
291: return i;
292: } else {
293: for (int i = index; i < elementCount; i++)
294: if (elem.equals(elementData[i]))
295: return i;
296: }
297: return -1;
298: }
299:
300: /**
301: * Returns the index of the last occurrence of the specified object in
302: * this vector.
303: *
304: * @param elem the desired component.
305: * @return the index of the last occurrence of the specified object in
306: * this vector; returns <code>-1</code> if the object is not found.
307: * @since JDK1.0
308: */
309: public int lastIndexOf(Object elem) {
310: return lastIndexOf(elem, elementCount - 1);
311: }
312:
313: /**
314: * Searches backwards for the specified object, starting from the
315: * specified index, and returns an index to it.
316: *
317: * @param elem the desired component.
318: * @param index the index to start searching from.
319: * @return the index of the last occurrence of the specified object in this
320: * vector at position less than <code>index</code> in the vector;
321: * <code>-1</code> if the object is not found.
322: * @exception IndexOutOfBoundsException if <tt>index</tt> is greater
323: * than or equal to the current size of this vector.
324: * @since JDK1.0
325: */
326: public synchronized int lastIndexOf(Object elem, int index) {
327: if (index >= elementCount) {
328: throw new IndexOutOfBoundsException(
329: /* #ifdef VERBOSE_EXCEPTIONS */
330: /// skipped index + " >= " + elementCount
331: /* #endif */
332: );
333: }
334:
335: if (elem == null) {
336: for (int i = index; i >= 0; i--)
337: if (elementData[i] == null)
338: return i;
339: } else {
340: for (int i = index; i >= 0; i--)
341: if (elem.equals(elementData[i]))
342: return i;
343: }
344: return -1;
345: }
346:
347: /**
348: * Returns the component at the specified index.
349: *
350: * @param index an index into this vector.
351: * @return the component at the specified index.
352: * @exception ArrayIndexOutOfBoundsException if an invalid index was
353: * given.
354: * @since JDK1.0
355: */
356: public synchronized Object elementAt(int index) {
357: if (index >= elementCount) {
358: throw new ArrayIndexOutOfBoundsException(
359: /* #ifdef VERBOSE_EXCEPTIONS */
360: /// skipped index + " >= " + elementCount
361: /* #endif */
362: );
363: }
364: return elementData[index];
365: }
366:
367: /**
368: * Returns the first component of this vector.
369: *
370: * @return the first component of this vector.
371: * @exception NoSuchElementException if this vector has no components.
372: * @since JDK1.0
373: */
374: public synchronized Object firstElement() {
375: if (elementCount == 0) {
376: throw new NoSuchElementException();
377: }
378: return elementData[0];
379: }
380:
381: /**
382: * Returns the last component of the vector.
383: *
384: * @return the last component of the vector, i.e., the component at index
385: * <code>size() - 1</code>.
386: * @exception NoSuchElementException if this vector is empty.
387: * @since JDK1.0
388: */
389: public synchronized Object lastElement() {
390: if (elementCount == 0) {
391: throw new NoSuchElementException();
392: }
393: return elementData[elementCount - 1];
394: }
395:
396: /**
397: * Sets the component at the specified <code>index</code> of this
398: * vector to be the specified object. The previous component at that
399: * position is discarded.
400: * <p>
401: * The index must be a value greater than or equal to <code>0</code>
402: * and less than the current size of the vector.
403: *
404: * @param obj what the component is to be set to.
405: * @param index the specified index.
406: * @exception ArrayIndexOutOfBoundsException if the index was invalid.
407: * @see java.util.Vector#size()
408: * @since JDK1.0
409: */
410: public synchronized void setElementAt(Object obj, int index) {
411: if (index >= elementCount) {
412: throw new ArrayIndexOutOfBoundsException(
413: /* #ifdef VERBOSE_EXCEPTIONS */
414: /// skipped index + " >= " +
415: /// skipped elementCount
416: /* #endif */
417: );
418: }
419: elementData[index] = obj;
420: }
421:
422: /**
423: * Deletes the component at the specified index. Each component in
424: * this vector with an index greater or equal to the specified
425: * <code>index</code> is shifted downward to have an index one
426: * smaller than the value it had previously.
427: * <p>
428: * The index must be a value greater than or equal to <code>0</code>
429: * and less than the current size of the vector.
430: *
431: * @param index the index of the object to remove.
432: * @exception ArrayIndexOutOfBoundsException if the index was invalid.
433: * @see java.util.Vector#size()
434: * @since JDK1.0
435: */
436: public synchronized void removeElementAt(int index) {
437: if (index >= elementCount) {
438: throw new ArrayIndexOutOfBoundsException(
439: /* #ifdef VERBOSE_EXCEPTIONS */
440: /// skipped index + " >= " +
441: /// skipped elementCount
442: /* #endif */
443: );
444: } else if (index < 0) {
445: throw new ArrayIndexOutOfBoundsException(
446: /* #ifdef VERBOSE_EXCEPTIONS */
447: /// skipped index
448: /* #endif */
449: );
450: }
451: int j = elementCount - index - 1;
452: if (j > 0) {
453: JVM.unchecked_obj_arraycopy(elementData, index + 1,
454: elementData, index, j);
455: }
456: elementCount--;
457: elementData[elementCount] = null; /* to let gc do its work */
458: }
459:
460: /**
461: * Inserts the specified object as a component in this vector at the
462: * specified <code>index</code>. Each component in this vector with
463: * an index greater or equal to the specified <code>index</code> is
464: * shifted upward to have an index one greater than the value it had
465: * previously.
466: * <p>
467: * The index must be a value greater than or equal to <code>0</code>
468: * and less than or equal to the current size of the vector.
469: *
470: * @param obj the component to insert.
471: * @param index where to insert the new component.
472: * @exception ArrayIndexOutOfBoundsException if the index was invalid.
473: * @see java.util.Vector#size()
474: * @since JDK1.0
475: */
476: public synchronized void insertElementAt(Object obj, int index) {
477: int newcount = elementCount + 1;
478: if (index < 0 || index >= newcount) {
479: throw new ArrayIndexOutOfBoundsException(
480: /* #ifdef VERBOSE_EXCEPTIONS */
481: /// skipped index + " > " + elementCount
482: /* #endif */
483: );
484: }
485: if (newcount > elementData.length) {
486: ensureCapacityHelper(newcount);
487: }
488: JVM.unchecked_obj_arraycopy(elementData, index, elementData,
489: index + 1, elementCount - index);
490: elementData[index] = obj;
491: elementCount++;
492: }
493:
494: /**
495: * Adds the specified component to the end of this vector,
496: * increasing its size by one. The capacity of this vector is
497: * increased if its size becomes greater than its capacity.
498: *
499: * @param obj the component to be added.
500: * @since JDK1.0
501: */
502: public synchronized void addElement(Object obj) {
503: int newcount = elementCount + 1;
504: if (newcount > elementData.length) {
505: ensureCapacityHelper(newcount);
506: }
507: elementData[elementCount++] = obj;
508: }
509:
510: /**
511: * Removes the first occurrence of the argument from this vector. If
512: * the object is found in this vector, each component in the vector
513: * with an index greater or equal to the object's index is shifted
514: * downward to have an index one smaller than the value it had previously.
515: *
516: * @param obj the component to be removed.
517: * @return <code>true</code> if the argument was a component of this
518: * vector; <code>false</code> otherwise.
519: * @since JDK1.0
520: */
521: public synchronized boolean removeElement(Object obj) {
522: int i = indexOf(obj);
523: if (i >= 0) {
524: removeElementAt(i);
525: return true;
526: }
527: return false;
528: }
529:
530: /**
531: * Removes all components from this vector and sets its size to zero.
532: *
533: * @since JDK1.0
534: */
535: public synchronized void removeAllElements() {
536: for (int i = 0; i < elementCount; i++) {
537: elementData[i] = null;
538: }
539: elementCount = 0;
540: }
541:
542: /**
543: * Returns a string representation of this vector.
544: *
545: * @return a string representation of this vector.
546: * @since JDK1.0
547: */
548: public synchronized String toString() {
549: int max = size() - 1;
550: StringBuffer buf = new StringBuffer();
551: Enumeration e = elements();
552: buf.append("[");
553:
554: for (int i = 0; i <= max; i++) {
555: buf.append(e.nextElement());
556: if (i < max) {
557: buf.append(", ");
558: }
559: }
560: buf.append("]");
561: return buf.toString();
562: }
563: }
564:
565: final class VectorEnumerator implements Enumeration {
566: Vector vector;
567: int count;
568:
569: VectorEnumerator(Vector v) {
570: vector = v;
571: count = 0;
572: }
573:
574: public boolean hasMoreElements() {
575: return count < vector.elementCount;
576: }
577:
578: public Object nextElement() {
579: synchronized (vector) {
580: if (count < vector.elementCount) {
581: return vector.elementData[count++];
582: }
583: }
584: throw new NoSuchElementException(
585: /* #ifdef VERBOSE_EXCEPTIONS */
586: /// skipped "VectorEnumerator"
587: /* #endif */
588: );
589: }
590: }
|