这里列出java.util.Vector容器的源代码。
Vector类型声明:
public class Vector extends AbstractList
implements List, RandomAccess, Cloneable, Serializable
实现了随意读取,可复制和可序列化接口
private static final long serialVersionUID = -2767605614048989439L;
protected T[] elementData;
protected int elementCount;
protected int capacityIncrement;
其中,T[] elementData是Vector存储的核心,为一个泛型数组。另外有一个标志容量的变量elementCount,另一个capacityIncrement是用来表征数组elementData扩容是的增量。
133: public Vector(Collection c)
134: {
135: elementCount = c.size();
136: elementData = c.toArray((T[]) new Object[elementCount]);
137: }
如上是根据另一个容器来构造Vector容器。
148: public Vector(int initialCapacity, int capacityIncrement)
149: {
150: if (initialCapacity < 0)
151: throw new IllegalArgumentException();
152: elementData = (T[]) new Object[initialCapacity];
153: this.capacityIncrement = capacityIncrement;
154: }
通过初始化elementData大小和增量来初始化Vector。
163: public Vector(int initialCapacity)
164: {
165: this(initialCapacity, 0);
166: }
通过初始化elementData容量来初始化Vector,其中增量默认为0.
120: public Vector()
121: {
122: this(10, 0);
123: }
最后一个构造函数最直接了当,初始化容量10,增量为0。
然后Vector定义两个修改elementData数组的成员函数,一个负责拷贝,一个负责压缩。
179: public synchronized void copyInto(Object[] a)
180: {
181: System.arraycopy(elementData, 0, a, 0, elementCount);
182: }
189: public synchronized void trimToSize()
190: {
195: T[] newArray = (T[]) new Object[elementCount];
196: System.arraycopy(elementData, 0, newArray, 0, elementCount);
197: elementData = newArray;
198: }
两个函数都是将现有数组复制到新的数组来实现扩容或压缩。
每当Vector有新元素添加时,需要检测当前elementData是否已满,这个函数如下,同时ensureCapacity还会将数组进行扩容:
210: public synchronized void ensureCapacity(int minCapacity)
211: {
212: if (elementData.length >= minCapacity)
213: return;
214:
215: int newCapacity;
216: if (capacityIncrement <= 0)
217: newCapacity = elementData.length * 2;
218: else
219: newCapacity = elementData.length + capacityIncrement;
220:
221: T[] newArray = (T[]) new Object[Math.max(newCapacity, minCapacity)];
222:
223: System.arraycopy(elementData, 0, newArray, 0, elementCount);
224: elementData = newArray;
225: }
如果需要给数组制定一个新的长度可以使用setSize()方法。
236: public synchronized void setSize(int newSize)
237: {
241: modCount++;
242: ensureCapacity(newSize);
243: if (newSize < elementCount)
244: Arrays.fill(elementData, newSize, elementCount, null);
245: elementCount = newSize;
246: }
Vector提供一个迭代器来遍历数组:
287: public Enumeration elements()
288: {
289: return new Enumeration()
290: {
291: private int i = 0;
292:
293: public boolean hasMoreElements()
294: {
295: return i < elementCount;
296: }
297:
298: public T nextElement()
299: {
300: if (i >= elementCount)
301: throw new NoSuchElementException();
302: return elementData[i++];
303: }
304: };
305: }
添加元素:
622: public boolean add(T o)
623: {
624: addElement(o);
625: return true;
626: }
其中添加方法定义如下:
475: public synchronized void addElement(T obj)
476: {
477: if (elementCount == elementData.length)
478: ensureCapacity(elementCount + 1);
479: modCount++;
480: elementData[elementCount++] = obj;
481: }
650: public void add(int index, T element)
651: {
652: insertElementAt(element, index);
653: }
在添加时加入添加位置,其中插入值方法定义如下:
457: public synchronized void insertElementAt(T obj, int index)
458: {
459: checkBoundInclusive(index);
460: if (elementCount == elementData.length)
461: ensureCapacity(elementCount + 1);
462: modCount++;
463: System.arraycopy(elementData, index, elementData, index + 1,
464: elementCount - index);
465: elementCount++;
466: elementData[index] = obj;
467: }
同时也可以将一个容器直接添加到Vector中:
786: public synchronized boolean addAll(int index, Collection c)
787: {
788: checkBoundInclusive(index);
789: Iterator itr = c.iterator();
790: int csize = c.size();
791:
792: modCount++;
793: ensureCapacity(elementCount + csize);
794: int end = index + csize;
795: if (elementCount > 0 && index != elementCount)
796: System.arraycopy(elementData, index,
797: elementData, end, elementCount - index);
798: elementCount += csize;
799: for ( ; index < end; index++)
800: elementData[index] = itr.next();
801: return (csize > 0);
802: }
592: public T get(int index)
593: {
594: return elementAt(index);
595: }
388: public synchronized T elementAt(int index)
389: {
390: checkBoundExclusive(index);
391: return elementData[index];
392: }
修改索引值得方法:
430: public void setElementAt(T obj, int index)
431: {
432: set(index, obj);
433: }
其中set()方法定义如下:
607: public synchronized T set(int index, T element)
608: {
609: checkBoundExclusive(index);
610: T temp = elementData[index];
611: elementData[index] = element;
612: return temp;
613: }
679: public void clear()
680: {
681: removeAllElements();
682: }
其中removeAllElements()方法定义如下:
509: public synchronized void removeAllElements()
510: {
511: if (elementCount == 0)
512: return;
513:
514: modCount++;
515: Arrays.fill(elementData, 0, elementCount, null);
516: elementCount = 0;
517: }
525: public synchronized Object clone()
526: {
527: try
528: {
529: Vector clone = (Vector) super.clone();
530: clone.elementData = (Object[]) elementData.clone();
531: return clone;
532: }
533: catch (CloneNotSupportedException ex)
534: {
535: // Impossible to get here.
536: throw new InternalError(ex.toString());
537: }
538: }
这是一个深度复制,其中对elementData数组进行了新建。
Vector可以以数组形式输出一个给定数组中:
573: public synchronized S[] toArray(S[] a)
574: {
575: if (a.length < elementCount)
576: a = (S[]) Array.newInstance(a.getClass().getComponentType(),
577: elementCount);
578: else if (a.length > elementCount)
579: a[elementCount] = null;
580: System.arraycopy(elementData, 0, a, 0, elementCount);
581: return a;
582: }
860: public synchronized List subList(int fromIndex, int toIndex)
861: {
862: List sub = super.subList(fromIndex, toIndex);
865: return new Collections.SynchronizedList(this, sub);
866: }
同时也可以移除一段范围内的子数组:
878: protected void removeRange(int fromIndex, int toIndex)
879: {
880: int change = toIndex - fromIndex;
881: if (change > 0)
882: {
883: modCount++;
884: System.arraycopy(elementData, toIndex, elementData, fromIndex,
885: elementCount - toIndex);
886: int save = elementCount;
887: elementCount -= change;
888: Arrays.fill(elementData, elementCount, save, null);
889: }
890: else if (change < 0)
891: throw new IndexOutOfBoundsException();
892: }
931: private synchronized void writeObject(ObjectOutputStream s)
932: throws IOException
933: {
934: s.defaultWriteObject();
935: }
如下提供完整源代码供浏览。
源代码来源:http://developer.classpath.org/doc/java/util/Vector-source.html
1: /* Vector.java -- Class that provides growable arrays.
2: Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005, 2006,
3: Free Software Foundation, Inc.
4:
5: This file is part of GNU Classpath.
6:
7: GNU Classpath is free software; you can redistribute it and/or modify
8: it under the terms of the GNU General Public License as published by
9: the Free Software Foundation; either version 2, or (at your option)
10: any later version.
11:
12: GNU Classpath is distributed in the hope that it will be useful, but
13: WITHOUT ANY WARRANTY; without even the implied warranty of
14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15: General Public License for more details.
16:
17: You should have received a copy of the GNU General Public License
18: along with GNU Classpath; see the file COPYING. If not, write to the
19: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20: 02110-1301 USA.
21:
22: Linking this library statically or dynamically with other modules is
23: making a combined work based on this library. Thus, the terms and
24: conditions of the GNU General Public License cover the whole
25: combination.
26:
27: As a special exception, the copyright holders of this library give you
28: permission to link this library with independent modules to produce an
29: executable, regardless of the license terms of these independent
30: modules, and to copy and distribute the resulting executable under
31: terms of your choice, provided that you also meet, for each linked
32: independent module, the terms and conditions of the license of that
33: module. An independent module is a module which is not derived from
34: or based on this library. If you modify this library, you may extend
35: this exception to your version of the library, but you are not
36: obligated to do so. If you do not wish to do so, delete this
37: exception statement from your version. */
38:
39:
40: package java.util;
41:
42: import java.io.IOException;
43: import java.io.ObjectOutputStream;
44: import java.io.Serializable;
45: import java.lang.reflect.Array;
46:
47: /**
48: * The Vector
classes implements growable arrays of Objects.
49: * You can access elements in a Vector with an index, just as you
50: * can in a built in array, but Vectors can grow and shrink to accommodate
51: * more or fewer objects.
52: *
53: * Vectors try to mantain efficiency in growing by having a
54: * capacityIncrement
that can be specified at instantiation.
55: * When a Vector can no longer hold a new Object, it grows by the amount
56: * in capacityIncrement
. If this value is 0, the vector doubles in
57: * size.
58: *
59: * Vector implements the JDK 1.2 List interface, and is therefore a fully
60: * compliant Collection object. The iterators are fail-fast - if external
61: * code structurally modifies the vector, any operation on the iterator will
62: * then throw a {@link ConcurrentModificationException}. The Vector class is
63: * fully synchronized, but the iterators are not. So, when iterating over a
64: * vector, be sure to synchronize on the vector itself. If you don't want the
65: * expense of synchronization, use ArrayList instead. On the other hand, the
66: * Enumeration of elements() is not thread-safe, nor is it fail-fast; so it
67: * can lead to undefined behavior even in a single thread if you modify the
68: * vector during iteration.
69: *
70: * Note: Some methods, especially those specified by List, specify throwing
71: * {@link IndexOutOfBoundsException}, but it is easier to implement by
72: * throwing the subclass {@link ArrayIndexOutOfBoundsException}. Others
73: * directly specify this subclass.
74: *
75: * @author Scott G. Miller
76: * @author Bryce McKinlay
77: * @author Eric Blake ([email protected])
78: * @see Collection
79: * @see List
80: * @see ArrayList
81: * @see LinkedList
82: * @since 1.0
83: * @status updated to 1.4
84: */
85: public class Vector extends AbstractList
86: implements List, RandomAccess, Cloneable, Serializable
87: {
88: /**
89: * Compatible with JDK 1.0+.
90: */
91: private static final long serialVersionUID = -2767605614048989439L;
92:
93: /**
94: * The internal array used to hold members of a Vector. The elements are
95: * in positions 0 through elementCount - 1, and all remaining slots are null.
96: * @serial the elements
97: */
98: protected T[] elementData;
99:
100: /**
101: * The number of elements currently in the vector, also returned by
102: * {@link #size}.
103: * @serial the size
104: */
105: protected int elementCount;
106:
107: /**
108: * The amount the Vector's internal array should be increased in size when
109: * a new element is added that exceeds the current size of the array,
110: * or when {@link #ensureCapacity} is called. If <= 0, the vector just
111: * doubles in size.
112: * @serial the amount to grow the vector by
113: */
114: protected int capacityIncrement;
115:
116: /**
117: * Constructs an empty vector with an initial size of 10, and
118: * a capacity increment of 0
119: */
120: public Vector()
121: {
122: this(10, 0);
123: }
124:
125: /**
126: * Constructs a vector containing the contents of Collection, in the
127: * order given by the collection.
128: *
129: * @param c collection of elements to add to the new vector
130: * @throws NullPointerException if c is null
131: * @since 1.2
132: */
133: public Vector(Collection c)
134: {
135: elementCount = c.size();
136: elementData = c.toArray((T[]) new Object[elementCount]);
137: }
138:
139: /**
140: * Constructs a Vector with the initial capacity and capacity
141: * increment specified.
142: *
143: * @param initialCapacity the initial size of the Vector's internal array
144: * @param capacityIncrement the amount the internal array should be
145: * increased by when necessary, 0 to double the size
146: * @throws IllegalArgumentException if initialCapacity < 0
147: */
148: public Vector(int initialCapacity, int capacityIncrement)
149: {
150: if (initialCapacity < 0)
151: throw new IllegalArgumentException();
152: elementData = (T[]) new Object[initialCapacity];
153: this.capacityIncrement = capacityIncrement;
154: }
155:
156: /**
157: * Constructs a Vector with the initial capacity specified, and a capacity
158: * increment of 0 (double in size).
159: *
160: * @param initialCapacity the initial size of the Vector's internal array
161: * @throws IllegalArgumentException if initialCapacity < 0
162: */
163: public Vector(int initialCapacity)
164: {
165: this(initialCapacity, 0);
166: }
167:
168: /**
169: * Copies the contents of the Vector into the provided array. If the
170: * array is too small to fit all the elements in the Vector, an
171: * {@link IndexOutOfBoundsException} is thrown without modifying the array.
172: * Old elements in the array are overwritten by the new elements.
173: *
174: * @param a target array for the copy
175: * @throws IndexOutOfBoundsException the array is not large enough
176: * @throws NullPointerException the array is null
177: * @see #toArray(Object[])
178: */
179: public synchronized void copyInto(Object[] a)
180: {
181: System.arraycopy(elementData, 0, a, 0, elementCount);
182: }
183:
184: /**
185: * Trims the Vector down to size. If the internal data array is larger
186: * than the number of Objects its holding, a new array is constructed
187: * that precisely holds the elements. Otherwise this does nothing.
188: */
189: public synchronized void trimToSize()
190: {
191: // Don't bother checking for the case where size() == the capacity of the
192: // vector since that is a much less likely case; it's more efficient to
193: // not do the check and lose a bit of performance in that infrequent case
194:
195: T[] newArray = (T[]) new Object[elementCount];
196: System.arraycopy(elementData, 0, newArray, 0, elementCount);
197: elementData = newArray;
198: }
199:
200: /**
201: * Ensures that minCapacity
elements can fit within this Vector.
202: * If elementData
is too small, it is expanded as follows:
203: * If the elementCount + capacityIncrement
is adequate, that
204: * is the new size. If capacityIncrement
is non-zero, the
205: * candidate size is double the current. If that is not enough, the new
206: * size is minCapacity
.
207: *
208: * @param minCapacity the desired minimum capacity, negative values ignored
209: */
210: public synchronized void ensureCapacity(int minCapacity)
211: {
212: if (elementData.length >= minCapacity)
213: return;
214:
215: int newCapacity;
216: if (capacityIncrement <= 0)
217: newCapacity = elementData.length * 2;
218: else
219: newCapacity = elementData.length + capacityIncrement;
220:
221: T[] newArray = (T[]) new Object[Math.max(newCapacity, minCapacity)];
222:
223: System.arraycopy(elementData, 0, newArray, 0, elementCount);
224: elementData = newArray;
225: }
226:
227: /**
228: * Explicitly sets the size of the vector (but not necessarily the size of
229: * the internal data array). If the new size is smaller than the old one,
230: * old values that don't fit are lost. If the new size is larger than the
231: * old one, the vector is padded with null entries.
232: *
233: * @param newSize The new size of the internal array
234: * @throws ArrayIndexOutOfBoundsException if the new size is negative
235: */
236: public synchronized void setSize(int newSize)
237: {
238: // Don't bother checking for the case where size() == the capacity of the
239: // vector since that is a much less likely case; it's more efficient to
240: // not do the check and lose a bit of performance in that infrequent case
241: modCount++;
242: ensureCapacity(newSize);
243: if (newSize < elementCount)
244: Arrays.fill(elementData, newSize, elementCount, null);
245: elementCount = newSize;
246: }
247:
248: /**
249: * Returns the size of the internal data array (not the amount of elements
250: * contained in the Vector).
251: *
252: * @return capacity of the internal data array
253: */
254: public synchronized int capacity()
255: {
256: return elementData.length;
257: }
258:
259: /**
260: * Returns the number of elements stored in this Vector.
261: *
262: * @return the number of elements in this Vector
263: */
264: public synchronized int size()
265: {
266: return elementCount;
267: }
268:
269: /**
270: * Returns true if this Vector is empty, false otherwise
271: *
272: * @return true if the Vector is empty, false otherwise
273: */
274: public synchronized boolean isEmpty()
275: {
276: return elementCount == 0;
277: }
278:
279: /**
280: * Returns an Enumeration of the elements of this Vector. The enumeration
281: * visits the elements in increasing index order, but is NOT thread-safe.
282: *
283: * @return an Enumeration
284: * @see #iterator()
285: */
286: // No need to synchronize as the Enumeration is not thread-safe!
287: public Enumeration elements()
288: {
289: return new Enumeration()
290: {
291: private int i = 0;
292:
293: public boolean hasMoreElements()
294: {
295: return i < elementCount;
296: }
297:
298: public T nextElement()
299: {
300: if (i >= elementCount)
301: throw new NoSuchElementException();
302: return elementData[i++];
303: }
304: };
305: }
306:
307: /**
308: * Returns true when elem
is contained in this Vector.
309: *
310: * @param elem the element to check
311: * @return true if the object is contained in this Vector, false otherwise
312: */
313: public boolean contains(Object elem)
314: {
315: return indexOf(elem, 0) >= 0;
316: }
317:
318: /**
319: * Returns the first occurrence of elem
in the Vector, or -1 if
320: * elem
is not found.
321: *
322: * @param elem the object to search for
323: * @return the index of the first occurrence, or -1 if not found
324: */
325: public int indexOf(Object elem)
326: {
327: return indexOf(elem, 0);
328: }
329:
330: /**
331: * Searches the vector starting at index
for object
332: * elem
and returns the index of the first occurrence of this
333: * Object. If the object is not found, or index is larger than the size
334: * of the vector, -1 is returned.
335: *
336: * @param e the Object to search for
337: * @param index start searching at this index
338: * @return the index of the next occurrence, or -1 if it is not found
339: * @throws IndexOutOfBoundsException if index < 0
340: */
341: public synchronized int indexOf(Object e, int index)
342: {
343: for (int i = index; i < elementCount; i++)
344: if (equals(e, elementData[i]))
345: return i;
346: return -1;
347: }
348:
349: /**
350: * Returns the last index of elem
within this Vector, or -1
351: * if the object is not within the Vector.
352: *
353: * @param elem the object to search for
354: * @return the last index of the object, or -1 if not found
355: */
356: public int lastIndexOf(Object elem)
357: {
358: return lastIndexOf(elem, elementCount - 1);
359: }
360:
361: /**
362: * Returns the index of the first occurrence of elem
, when
363: * searching backwards from index
. If the object does not
364: * occur in this Vector, or index is less than 0, -1 is returned.
365: *
366: * @param e the object to search for
367: * @param index the index to start searching in reverse from
368: * @return the index of the Object if found, -1 otherwise
369: * @throws IndexOutOfBoundsException if index >= size()
370: */
371: public synchronized int lastIndexOf(Object e, int index)
372: {
373: checkBoundExclusive(index);
374: for (int i = index; i >= 0; i--)
375: if (equals(e, elementData[i]))
376: return i;
377: return -1;
378: }
379:
380: /**
381: * Returns the Object stored at index
.
382: *
383: * @param index the index of the Object to retrieve
384: * @return the object at index
385: * @throws ArrayIndexOutOfBoundsException index < 0 || index >= size()
386: * @see #get(int)
387: */
388: public synchronized T elementAt(int index)
389: {
390: checkBoundExclusive(index);
391: return elementData[index];
392: }
393:
394: /**
395: * Returns the first element (index 0) in the Vector.
396: *
397: * @return the first Object in the Vector
398: * @throws NoSuchElementException the Vector is empty
399: */
400: public synchronized T firstElement()
401: {
402: if (elementCount == 0)
403: throw new NoSuchElementException();
404:
405: return elementData[0];
406: }
407:
408: /**
409: * Returns the last element in the Vector.
410: *
411: * @return the last Object in the Vector
412: * @throws NoSuchElementException the Vector is empty
413: */
414: public synchronized T lastElement()
415: {
416: if (elementCount == 0)
417: throw new NoSuchElementException();
418:
419: return elementData[elementCount - 1];
420: }
421:
422: /**
423: * Changes the element at index
to be obj
424: *
425: * @param obj the object to store
426: * @param index the position in the Vector to store the object
427: * @throws ArrayIndexOutOfBoundsException the index is out of range
428: * @see #set(int, Object)
429: */
430: public void setElementAt(T obj, int index)
431: {
432: set(index, obj);
433: }
434:
435: /**
436: * Removes the element at index
, and shifts all elements at
437: * positions greater than index to their index - 1.
438: *
439: * @param index the index of the element to remove
440: * @throws ArrayIndexOutOfBoundsException index < 0 || index >= size();
441: * @see #remove(int)
442: */
443: public void removeElementAt(int index)
444: {
445: remove(index);
446: }
447:
448: /**
449: * Inserts a new element into the Vector at index
. Any elements
450: * at or greater than index are shifted up one position.
451: *
452: * @param obj the object to insert
453: * @param index the index at which the object is inserted
454: * @throws ArrayIndexOutOfBoundsException index < 0 || index > size()
455: * @see #add(int, Object)
456: */
457: public synchronized void insertElementAt(T obj, int index)
458: {
459: checkBoundInclusive(index);
460: if (elementCount == elementData.length)
461: ensureCapacity(elementCount + 1);
462: modCount++;
463: System.arraycopy(elementData, index, elementData, index + 1,
464: elementCount - index);
465: elementCount++;
466: elementData[index] = obj;
467: }
468:
469: /**
470: * Adds an element to the Vector at the end of the Vector. The vector
471: * is increased by ensureCapacity(size() + 1) if needed.
472: *
473: * @param obj the object to add to the Vector
474: */
475: public synchronized void addElement(T obj)
476: {
477: if (elementCount == elementData.length)
478: ensureCapacity(elementCount + 1);
479: modCount++;
480: elementData[elementCount++] = obj;
481: }
482:
483: /**
484: * Removes the first (the lowest index) occurrence of the given object from
485: * the Vector. If such a remove was performed (the object was found), true
486: * is returned. If there was no such object, false is returned.
487: *
488: * @param obj the object to remove from the Vector
489: * @return true if the Object was in the Vector, false otherwise
490: * @see #remove(Object)
491: */
492: public synchronized boolean removeElement(Object obj)
493: {
494: int idx = indexOf(obj, 0);
495: if (idx >= 0)
496: {
497: remove(idx);
498: return true;
499: }
500: return false;
501: }
502:
503: /**
504: * Removes all elements from the Vector. Note that this does not
505: * resize the internal data array.
506: *
507: * @see #clear()
508: */
509: public synchronized void removeAllElements()
510: {
511: if (elementCount == 0)
512: return;
513:
514: modCount++;
515: Arrays.fill(elementData, 0, elementCount, null);
516: elementCount = 0;
517: }
518:
519: /**
520: * Creates a new Vector with the same contents as this one. The clone is
521: * shallow; elements are not cloned.
522: *
523: * @return the clone of this vector
524: */
525: public synchronized Object clone()
526: {
527: try
528: {
529: Vector clone = (Vector) super.clone();
530: clone.elementData = (Object[]) elementData.clone();
531: return clone;
532: }
533: catch (CloneNotSupportedException ex)
534: {
535: // Impossible to get here.
536: throw new InternalError(ex.toString());
537: }
538: }
539:
540: /**
541: * Returns an Object array with the contents of this Vector, in the order
542: * they are stored within this Vector. Note that the Object array returned
543: * is not the internal data array, and that it holds only the elements
544: * within the Vector. This is similar to creating a new Object[] with the
545: * size of this Vector, then calling Vector.copyInto(yourArray).
546: *
547: * @return an Object[] containing the contents of this Vector in order
548: * @since 1.2
549: */
550: public synchronized Object[] toArray()
551: {
552: Object[] newArray = new Object[elementCount];
553: copyInto(newArray);
554: return newArray;
555: }
556:
557: /**
558: * Returns an array containing the contents of this Vector.
559: * If the provided array is large enough, the contents are copied
560: * into that array, and a null is placed in the position size().
561: * In this manner, you can obtain the size of a Vector by the position
562: * of the null element, if you know the vector does not itself contain
563: * null entries. If the array is not large enough, reflection is used
564: * to create a bigger one of the same runtime type.
565: *
566: * @param a an array to copy the Vector into if large enough
567: * @return an array with the contents of this Vector in order
568: * @throws ArrayStoreException the runtime type of the provided array
569: * cannot hold the elements of the Vector
570: * @throws NullPointerException if a
is null
571: * @since 1.2
572: */
573: public synchronized S[] toArray(S[] a)
574: {
575: if (a.length < elementCount)
576: a = (S[]) Array.newInstance(a.getClass().getComponentType(),
577: elementCount);
578: else if (a.length > elementCount)
579: a[elementCount] = null;
580: System.arraycopy(elementData, 0, a, 0, elementCount);
581: return a;
582: }
583:
584: /**
585: * Returns the element at position index
.
586: *
587: * @param index the position from which an element will be retrieved
588: * @return the element at that position
589: * @throws ArrayIndexOutOfBoundsException index < 0 || index >= size()
590: * @since 1.2
591: */
592: public T get(int index)
593: {
594: return elementAt(index);
595: }
596:
597: /**
598: * Puts element
into the Vector at position index
599: * and returns the Object that previously occupied that position.
600: *
601: * @param index the index within the Vector to place the Object
602: * @param element the Object to store in the Vector
603: * @return the previous object at the specified index
604: * @throws ArrayIndexOutOfBoundsException index < 0 || index >= size()
605: * @since 1.2
606: */
607: public synchronized T set(int index, T element)
608: {
609: checkBoundExclusive(index);
610: T temp = elementData[index];
611: elementData[index] = element;
612: return temp;
613: }
614:
615: /**
616: * Adds an object to the Vector.
617: *
618: * @param o the element to add to the Vector
619: * @return true, as specified by List
620: * @since 1.2
621: */
622: public boolean add(T o)
623: {
624: addElement(o);
625: return true;
626: }
627:
628: /**
629: * Removes the given Object from the Vector. If it exists, true
630: * is returned, if not, false is returned.
631: *
632: * @param o the object to remove from the Vector
633: * @return true if the Object existed in the Vector, false otherwise
634: * @since 1.2
635: */
636: public boolean remove(Object o)
637: {
638: return removeElement(o);
639: }
640:
641: /**
642: * Adds an object at the specified index. Elements at or above
643: * index are shifted up one position.
644: *
645: * @param index the index at which to add the element
646: * @param element the element to add to the Vector
647: * @throws ArrayIndexOutOfBoundsException index < 0 || index > size()
648: * @since 1.2
649: */
650: public void add(int index, T element)
651: {
652: insertElementAt(element, index);
653: }
654:
655: /**
656: * Removes the element at the specified index, and returns it.
657: *
658: * @param index the position from which to remove the element
659: * @return the object removed
660: * @throws ArrayIndexOutOfBoundsException index < 0 || index >= size()
661: * @since 1.2
662: */
663: public synchronized T remove(int index)
664: {
665: checkBoundExclusive(index);
666: T temp = elementData[index];
667: modCount++;
668: elementCount--;
669: if (index < elementCount)
670: System.arraycopy(elementData, index + 1, elementData, index,
671: elementCount - index);
672: elementData[elementCount] = null;
673: return temp;
674: }
675:
676: /**
677: * Clears all elements in the Vector and sets its size to 0.
678: */
679: public void clear()
680: {
681: removeAllElements();
682: }
683:
684: /**
685: * Returns true if this Vector contains all the elements in c.
686: *
687: * @param c the collection to compare to
688: * @return true if this vector contains all elements of c
689: * @throws NullPointerException if c is null
690: * @since 1.2
691: */
692: public synchronized boolean containsAll(Collection c)
693: {
694: // Here just for the sychronization.
695: return super.containsAll(c);
696: }
697:
698: /**
699: * Appends all elements of the given collection to the end of this Vector.
700: * Behavior is undefined if the collection is modified during this operation
701: * (for example, if this == c).
702: *
703: * @param c the collection to append
704: * @return true if this vector changed, in other words c was not empty
705: * @throws NullPointerException if c is null
706: * @since 1.2
707: */
708: public synchronized boolean addAll(Collection c)
709: {
710: return addAll(elementCount, c);
711: }
712:
713: /**
714: * Remove from this vector all elements contained in the given collection.
715: *
716: * @param c the collection to filter out
717: * @return true if this vector changed
718: * @throws NullPointerException if c is null
719: * @since 1.2
720: */
721: public synchronized boolean removeAll(Collection c)
722: {
723: // The NullPointerException is thrown implicitly when the Vector
724: // is not empty and c is null. The RI allows null arguments when
725: // the vector is empty. See Mauve test:
726: // gnu/testlet/java/util/Vector/removeAll.java
727:
728: int i;
729: int j;
730: for (i = 0; i < elementCount; i++)
731: if (c.contains(elementData[i]))
732: break;
733: if (i == elementCount)
734: return false;
735:
736: modCount++;
737: for (j = i++; i < elementCount; i++)
738: if (! c.contains(elementData[i]))
739: elementData[j++] = elementData[i];
740: elementCount -= i - j;
741: return true;
742: }
743:
744: /**
745: * Retain in this vector only the elements contained in the given collection.
746: *
747: * @param c the collection to filter by
748: * @return true if this vector changed
749: * @throws NullPointerException if c is null
750: * @since 1.2
751: */
752: public synchronized boolean retainAll(Collection c)
753: {
754: // The NullPointerException is thrown implicitly when the Vector
755: // is not empty and c is null. The RI allows null arguments when
756: // the vector is empty. See Mauve test:
757: // gnu/testlet/java/util/Vector/retainAll.java
758:
759: int i;
760: int j;
761: for (i = 0; i < elementCount; i++)
762: if (! c.contains(elementData[i]))
763: break;
764: if (i == elementCount)
765: return false;
766:
767: modCount++;
768: for (j = i++; i < elementCount; i++)
769: if (c.contains(elementData[i]))
770: elementData[j++] = elementData[i];
771: elementCount -= i - j;
772: return true;
773: }
774:
775: /**
776: * Inserts all elements of the given collection at the given index of
777: * this Vector. Behavior is undefined if the collection is modified during
778: * this operation (for example, if this == c).
779: *
780: * @param c the collection to append
781: * @return true if this vector changed, in other words c was not empty
782: * @throws NullPointerException if c is null
783: * @throws ArrayIndexOutOfBoundsException index < 0 || index > size()
784: * @since 1.2
785: */
786: public synchronized boolean addAll(int index, Collection c)
787: {
788: checkBoundInclusive(index);
789: Iterator itr = c.iterator();
790: int csize = c.size();
791:
792: modCount++;
793: ensureCapacity(elementCount + csize);
794: int end = index + csize;
795: if (elementCount > 0 && index != elementCount)
796: System.arraycopy(elementData, index,
797: elementData, end, elementCount - index);
798: elementCount += csize;
799: for ( ; index < end; index++)
800: elementData[index] = itr.next();
801: return (csize > 0);
802: }
803:
804: /**
805: * Compares this to the given object.
806: *
807: * @param o the object to compare to
808: * @return true if the two are equal
809: * @since 1.2
810: */
811: public synchronized boolean equals(Object o)
812: {
813: // Here just for the sychronization.
814: return super.equals(o);
815: }
816:
817: /**
818: * Computes the hashcode of this object.
819: *
820: * @return the hashcode
821: * @since 1.2
822: */
823: public synchronized int hashCode()
824: {
825: // Here just for the sychronization.
826: return super.hashCode();
827: }
828:
829: /**
830: * Returns a string representation of this Vector in the form
831: * "[element0, element1, ... elementN]".
832: *
833: * @return the String representation of this Vector
834: */
835: public synchronized String toString()
836: {
837: // Here just for the sychronization.
838: return super.toString();
839: }
840:
841: /**
842: * Obtain a List view of a subsection of this list, from fromIndex
843: * (inclusive) to toIndex (exclusive). If the two indices are equal, the
844: * sublist is empty. The returned list is modifiable, and changes in one
845: * reflect in the other. If this list is structurally modified in
846: * any way other than through the returned list, the result of any subsequent
847: * operations on the returned list is undefined.
848: *
849: *
850: * @param fromIndex the index that the returned list should start from
851: * (inclusive)
852: * @param toIndex the index that the returned list should go to (exclusive)
853: * @return a List backed by a subsection of this vector
854: * @throws IndexOutOfBoundsException if fromIndex < 0
855: * || toIndex > size()
856: * @throws IllegalArgumentException if fromIndex > toIndex
857: * @see ConcurrentModificationException
858: * @since 1.2
859: */
860: public synchronized List subList(int fromIndex, int toIndex)
861: {
862: List sub = super.subList(fromIndex, toIndex);
863: // We must specify the correct object to synchronize upon, hence the
864: // use of a non-public API
865: return new Collections.SynchronizedList(this, sub);
866: }
867:
868: /**
869: * Removes a range of elements from this list.
870: * Does nothing when toIndex is equal to fromIndex.
871: *
872: * @param fromIndex the index to start deleting from (inclusive)
873: * @param toIndex the index to delete up to (exclusive)
874: * @throws IndexOutOfBoundsException if fromIndex > toIndex
875: */
876: // This does not need to be synchronized, because it is only called through
877: // clear() of a sublist, and clear() had already synchronized.
878: protected void removeRange(int fromIndex, int toIndex)
879: {
880: int change = toIndex - fromIndex;
881: if (change > 0)
882: {
883: modCount++;
884: System.arraycopy(elementData, toIndex, elementData, fromIndex,
885: elementCount - toIndex);
886: int save = elementCount;
887: elementCount -= change;
888: Arrays.fill(elementData, elementCount, save, null);
889: }
890: else if (change < 0)
891: throw new IndexOutOfBoundsException();
892: }
893:
894: /**
895: * Checks that the index is in the range of possible elements (inclusive).
896: *
897: * @param index the index to check
898: * @throws ArrayIndexOutOfBoundsException if index > size
899: */
900: private void checkBoundInclusive(int index)
901: {
902: // Implementation note: we do not check for negative ranges here, since
903: // use of a negative index will cause an ArrayIndexOutOfBoundsException
904: // with no effort on our part.
905: if (index > elementCount)
906: throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount);
907: }
908:
909: /**
910: * Checks that the index is in the range of existing elements (exclusive).
911: *
912: * @param index the index to check
913: * @throws ArrayIndexOutOfBoundsException if index >= size
914: */
915: private void checkBoundExclusive(int index)
916: {
917: // Implementation note: we do not check for negative ranges here, since
918: // use of a negative index will cause an ArrayIndexOutOfBoundsException
919: // with no effort on our part.
920: if (index >= elementCount)
921: throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
922: }
923:
924: /**
925: * Serializes this object to the given stream.
926: *
927: * @param s the stream to write to
928: * @throws IOException if the underlying stream fails
929: * @serialData just calls default write function
930: */
931: private synchronized void writeObject(ObjectOutputStream s)
932: throws IOException
933: {
934: s.defaultWriteObject();
935: }
936:
937: }