Vector.java 28.1 KB
Newer Older
Bryce McKinlay committed
1
/* Vector.java -- Class that provides growable arrays.
2
   Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
Tom Tromey committed
3

Bryce McKinlay committed
4
This file is part of GNU Classpath.
Tom Tromey committed
5

Bryce McKinlay committed
6 7 8 9
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.
Tom Tromey committed
10

Bryce McKinlay committed
11 12 13 14 15 16 17 18 19 20
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.

21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.

As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent
modules, and to copy and distribute the resulting executable under
terms of your choice, provided that you also meet, for each linked
independent module, the terms and conditions of the license of that
module.  An independent module is a module which is not derived from
or based on this library.  If you modify this library, you may extend
this exception to your version of the library, but you are not
obligated to do so.  If you do not wish to do so, delete this
exception statement from your version. */
Tom Tromey committed
37

Bryce McKinlay committed
38 39 40

package java.util;
import java.lang.reflect.Array;
Tom Tromey committed
41 42 43
import java.io.Serializable;

/**
44
 * The <code>Vector</code> classes implements growable arrays of Objects.
Bryce McKinlay committed
45
 * You can access elements in a Vector with an index, just as you
46
 * can in a built in array, but Vectors can grow and shrink to accommodate
47
 * more or fewer objects.<p>
Bryce McKinlay committed
48 49
 *
 * Vectors try to mantain efficiency in growing by having a
50
 * <code>capacityIncrement</code> that can be specified at instantiation.
Bryce McKinlay committed
51
 * When a Vector can no longer hold a new Object, it grows by the amount
52 53
 * in <code>capacityIncrement</code>. If this value is 0, the vector doubles in
 * size.<p>
Bryce McKinlay committed
54
 *
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
 * Vector implements the JDK 1.2 List interface, and is therefore a fully
 * compliant Collection object. The iterators are fail-fast - if external
 * code structurally modifies the vector, any operation on the iterator will
 * then throw a {@link ConcurrentModificationException}. The Vector class is
 * fully synchronized, but the iterators are not. So, when iterating over a
 * vector, be sure to synchronize on the vector itself.  If you don't want the
 * expense of synchronization, use ArrayList instead. On the other hand, the
 * Enumeration of elements() is not thread-safe, nor is it fail-fast; so it
 * can lead to undefined behavior even in a single thread if you modify the
 * vector during iteration.<p>
 *
 * Note: Some methods, especially those specified by List, specify throwing
 * {@link IndexOutOfBoundsException}, but it is easier to implement by
 * throwing the subclass {@link ArrayIndexOutOfBoundsException}. Others
 * directly specify this subclass.
Bryce McKinlay committed
70 71
 *
 * @author Scott G. Miller
72 73 74 75 76 77 78 79
 * @author Bryce McKinlay
 * @author Eric Blake <ebb9@email.byu.edu>
 * @see Collection
 * @see List
 * @see ArrayList
 * @see LinkedList
 * @since 1.0
 * @status updated to 1.4
Tom Tromey committed
80
 */
81 82
public class Vector extends AbstractList
  implements List, RandomAccess, Cloneable, Serializable
Tom Tromey committed
83
{
Bryce McKinlay committed
84
  /**
85
   * Compatible with JDK 1.0+.
Bryce McKinlay committed
86
   */
87 88 89 90 91 92 93 94
  private static final long serialVersionUID = -2767605614048989439L;

  /**
   * The internal array used to hold members of a Vector. The elements are
   * in positions 0 through elementCount - 1, and all remaining slots are null.
   * @serial the elements
   */
  protected Object[] elementData;
Bryce McKinlay committed
95 96 97 98

  /**
   * The number of elements currently in the vector, also returned by
   * {@link #size}.
99
   * @serial the size
Bryce McKinlay committed
100
   */
101
  protected int elementCount;
Bryce McKinlay committed
102 103

  /**
104 105 106 107 108
   * The amount the Vector's internal array should be increased in size when
   * a new element is added that exceeds the current size of the array,
   * or when {@link #ensureCapacity} is called. If &lt;= 0, the vector just
   * doubles in size.
   * @serial the amount to grow the vector by
Bryce McKinlay committed
109
   */
110
  protected int capacityIncrement;
Tom Tromey committed
111

Bryce McKinlay committed
112 113 114 115 116
  /**
   * Constructs an empty vector with an initial size of 10, and
   * a capacity increment of 0
   */
  public Vector()
Tom Tromey committed
117
  {
118
    this(10, 0);
Tom Tromey committed
119 120
  }

Bryce McKinlay committed
121 122
  /**
   * Constructs a vector containing the contents of Collection, in the
123
   * order given by the collection.
Bryce McKinlay committed
124
   *
125 126 127
   * @param c collection of elements to add to the new vector
   * @throws NullPointerException if c is null
   * @since 1.2
Bryce McKinlay committed
128 129
   */
  public Vector(Collection c)
Tom Tromey committed
130
  {
131 132
    elementCount = c.size();
    elementData = c.toArray(new Object[elementCount]);
Tom Tromey committed
133 134
  }

Bryce McKinlay committed
135
  /**
136 137
   * Constructs a Vector with the initial capacity and capacity
   * increment specified.
Bryce McKinlay committed
138
   *
139 140 141 142
   * @param initialCapacity the initial size of the Vector's internal array
   * @param capacityIncrement the amount the internal array should be
   *        increased by when necessary, 0 to double the size
   * @throws IllegalArgumentException if initialCapacity &lt; 0
Bryce McKinlay committed
143 144
   */
  public Vector(int initialCapacity, int capacityIncrement)
Tom Tromey committed
145
  {
146 147
    if (initialCapacity < 0)
      throw new IllegalArgumentException();
Bryce McKinlay committed
148 149
    elementData = new Object[initialCapacity];
    this.capacityIncrement = capacityIncrement;
Tom Tromey committed
150 151
  }

Bryce McKinlay committed
152
  /**
153 154
   * Constructs a Vector with the initial capacity specified, and a capacity
   * increment of 0 (double in size).
Bryce McKinlay committed
155
   *
156 157
   * @param initialCapacity the initial size of the Vector's internal array
   * @throws IllegalArgumentException if initialCapacity &lt; 0
Bryce McKinlay committed
158 159
   */
  public Vector(int initialCapacity)
Tom Tromey committed
160
  {
161
    this(initialCapacity, 0);
Tom Tromey committed
162 163
  }

Bryce McKinlay committed
164
  /**
165 166 167 168
   * Copies the contents of a provided array into the Vector.  If the
   * array is too large to fit in the Vector, an IndexOutOfBoundsException
   * is thrown without modifying the array.  Old elements in the Vector are
   * overwritten by the new elements.
Bryce McKinlay committed
169
   *
170 171 172 173
   * @param a target array for the copy
   * @throws IndexOutOfBoundsException the array is not large enough
   * @throws NullPointerException the array is null
   * @see #toArray(Object[])
Bryce McKinlay committed
174
   */
175
  public synchronized void copyInto(Object[] a)
Tom Tromey committed
176
  {
177
    System.arraycopy(elementData, 0, a, 0, elementCount);
Tom Tromey committed
178 179
  }

Bryce McKinlay committed
180 181 182
  /**
   * Trims the Vector down to size.  If the internal data array is larger
   * than the number of Objects its holding, a new array is constructed
183
   * that precisely holds the elements. Otherwise this does nothing.
Bryce McKinlay committed
184 185
   */
  public synchronized void trimToSize()
Tom Tromey committed
186
  {
187 188 189
    // Don't bother checking for the case where size() == the capacity of the
    // vector since that is a much less likely case; it's more efficient to
    // not do the check and lose a bit of performance in that infrequent case
Tom Tromey committed
190

191
    Object[] newArray = new Object[elementCount];
Bryce McKinlay committed
192 193
    System.arraycopy(elementData, 0, newArray, 0, elementCount);
    elementData = newArray;
Tom Tromey committed
194 195
  }

Bryce McKinlay committed
196
  /**
197 198 199 200 201 202
   * Ensures that <code>minCapacity</code> elements can fit within this Vector.
   * If <code>elementData</code> is too small, it is expanded as follows:
   * If the <code>elementCount + capacityIncrement</code> is adequate, that
   * is the new size. If <code>capacityIncrement</code> is non-zero, the
   * candidate size is double the current. If that is not enough, the new
   * size is <code>minCapacity</code>.
Bryce McKinlay committed
203
   *
204
   * @param minCapacity the desired minimum capacity, negative values ignored
Bryce McKinlay committed
205 206
   */
  public synchronized void ensureCapacity(int minCapacity)
Tom Tromey committed
207
  {
Bryce McKinlay committed
208 209
    if (elementData.length >= minCapacity)
      return;
Tom Tromey committed
210

211
    int newCapacity;
Bryce McKinlay committed
212 213 214 215
    if (capacityIncrement <= 0)
      newCapacity = elementData.length * 2;
    else
      newCapacity = elementData.length + capacityIncrement;
216

Bryce McKinlay committed
217
    Object[] newArray = new Object[Math.max(newCapacity, minCapacity)];
Tom Tromey committed
218

219
    System.arraycopy(elementData, 0, newArray, 0, elementCount);
Bryce McKinlay committed
220
    elementData = newArray;
Tom Tromey committed
221 222
  }

Bryce McKinlay committed
223
  /**
224 225 226 227
   * Explicitly sets the size of the vector (but not necessarily the size of
   * the internal data array). If the new size is smaller than the old one,
   * old values that don't fit are lost. If the new size is larger than the
   * old one, the vector is padded with null entries.
Bryce McKinlay committed
228 229
   *
   * @param newSize The new size of the internal array
230
   * @throws ArrayIndexOutOfBoundsException if the new size is negative
Bryce McKinlay committed
231 232
   */
  public synchronized void setSize(int newSize)
Tom Tromey committed
233
  {
234 235 236
    // Don't bother checking for the case where size() == the capacity of the
    // vector since that is a much less likely case; it's more efficient to
    // not do the check and lose a bit of performance in that infrequent case
Bryce McKinlay committed
237
    modCount++;
238 239 240
    ensureCapacity(newSize);
    if (newSize < elementCount)
      Arrays.fill(elementData, newSize, elementCount, null);
Bryce McKinlay committed
241
    elementCount = newSize;
Tom Tromey committed
242 243
  }

Bryce McKinlay committed
244 245
  /**
   * Returns the size of the internal data array (not the amount of elements
246
   * contained in the Vector).
Bryce McKinlay committed
247
   *
248
   * @return capacity of the internal data array
Bryce McKinlay committed
249
   */
250
  public synchronized int capacity()
Tom Tromey committed
251
  {
Bryce McKinlay committed
252
    return elementData.length;
Tom Tromey committed
253 254
  }

Bryce McKinlay committed
255
  /**
256
   * Returns the number of elements stored in this Vector.
Bryce McKinlay committed
257
   *
258
   * @return the number of elements in this Vector
Bryce McKinlay committed
259
   */
260
  public synchronized int size()
Tom Tromey committed
261
  {
Bryce McKinlay committed
262
    return elementCount;
Tom Tromey committed
263 264
  }

Bryce McKinlay committed
265 266 267
  /**
   * Returns true if this Vector is empty, false otherwise
   *
268
   * @return true if the Vector is empty, false otherwise
Bryce McKinlay committed
269
   */
270
  public synchronized boolean isEmpty()
Tom Tromey committed
271
  {
Bryce McKinlay committed
272
    return elementCount == 0;
Tom Tromey committed
273 274
  }

Bryce McKinlay committed
275
  /**
276 277
   * Returns an Enumeration of the elements of this Vector. The enumeration
   * visits the elements in increasing index order, but is NOT thread-safe.
Bryce McKinlay committed
278
   *
279 280
   * @return an Enumeration
   * @see #iterator()
Bryce McKinlay committed
281
   */
282 283
  // No need to synchronize as the Enumeration is not thread-safe!
  public Enumeration elements()
Tom Tromey committed
284
  {
285 286 287 288 289
    return new Enumeration()
    {
      private int i = 0;

      public boolean hasMoreElements()
Tom Tromey committed
290
      {
291
        return i < elementCount;
Tom Tromey committed
292
      }
293 294 295 296 297 298 299 300

      public Object nextElement()
      {
        if (i >= elementCount)
          throw new NoSuchElementException();
        return elementData[i++];
      }
    };
Tom Tromey committed
301 302
  }

Bryce McKinlay committed
303
  /**
304
   * Returns true when <code>elem</code> is contained in this Vector.
Bryce McKinlay committed
305
   *
306 307
   * @param elem the element to check
   * @return true if the object is contained in this Vector, false otherwise
Bryce McKinlay committed
308
   */
309
  public boolean contains(Object elem)
Tom Tromey committed
310
  {
311
    return indexOf(elem, 0) >= 0;
Tom Tromey committed
312 313
  }

Bryce McKinlay committed
314
  /**
315 316
   * Returns the first occurrence of <code>elem</code> in the Vector, or -1 if
   * <code>elem</code> is not found.
Bryce McKinlay committed
317
   *
318 319
   * @param elem the object to search for
   * @return the index of the first occurrence, or -1 if not found
Bryce McKinlay committed
320
   */
321
  public int indexOf(Object elem)
Tom Tromey committed
322
  {
323
    return indexOf(elem, 0);
Tom Tromey committed
324 325
  }

Bryce McKinlay committed
326
  /**
327 328 329 330
   * Searches the vector starting at <code>index</code> for object
   * <code>elem</code> and returns the index of the first occurrence of this
   * Object.  If the object is not found, or index is larger than the size
   * of the vector, -1 is returned.
Bryce McKinlay committed
331
   *
332 333 334 335
   * @param e the Object to search for
   * @param index start searching at this index
   * @return the index of the next occurrence, or -1 if it is not found
   * @throws IndexOutOfBoundsException if index &lt; 0
Bryce McKinlay committed
336
   */
337
  public synchronized int indexOf(Object e, int index)
Tom Tromey committed
338
  {
339 340 341
    for (int i = index; i < elementCount; i++)
      if (equals(e, elementData[i]))
        return i;
Tom Tromey committed
342 343 344
    return -1;
  }

Bryce McKinlay committed
345
  /**
346 347
   * Returns the last index of <code>elem</code> within this Vector, or -1
   * if the object is not within the Vector.
Bryce McKinlay committed
348
   *
349 350
   * @param elem the object to search for
   * @return the last index of the object, or -1 if not found
Bryce McKinlay committed
351 352
   */
  public int lastIndexOf(Object elem)
Tom Tromey committed
353
  {
Bryce McKinlay committed
354 355
    return lastIndexOf(elem, elementCount - 1);
  }
Tom Tromey committed
356

Bryce McKinlay committed
357
  /**
358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
   * Returns the index of the first occurrence of <code>elem</code>, when
   * searching backwards from <code>index</code>.  If the object does not
   * occur in this Vector, or index is less than 0, -1 is returned.
   *
   * @param e the object to search for
   * @param index the index to start searching in reverse from
   * @return the index of the Object if found, -1 otherwise
   * @throws IndexOutOfBoundsException if index &gt;= size()
   */
  public synchronized int lastIndexOf(Object e, int index)
  {
    checkBoundExclusive(index);
    for (int i = index; i >= 0; i--)
      if (equals(e, elementData[i]))
        return i;
    return -1;
  }

  /**
   * Returns the Object stored at <code>index</code>.
Bryce McKinlay committed
378 379
   *
   * @param index the index of the Object to retrieve
380 381 382
   * @return the object at <code>index</code>
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
   * @see #get(int)
Bryce McKinlay committed
383 384 385
   */
  public synchronized Object elementAt(int index)
  {
386
    checkBoundExclusive(index);
Bryce McKinlay committed
387
    return elementData[index];
Tom Tromey committed
388 389
  }

Bryce McKinlay committed
390
  /**
391
   * Returns the first element (index 0) in the Vector.
Bryce McKinlay committed
392
   *
393
   * @return the first Object in the Vector
Bryce McKinlay committed
394 395 396
   * @throws NoSuchElementException the Vector is empty
   */
  public synchronized Object firstElement()
Tom Tromey committed
397
  {
Bryce McKinlay committed
398 399 400
    if (elementCount == 0)
      throw new NoSuchElementException();

401
    return elementData[0];
Tom Tromey committed
402 403
  }

Bryce McKinlay committed
404
  /**
405
   * Returns the last element in the Vector.
Bryce McKinlay committed
406
   *
407
   * @return the last Object in the Vector
Bryce McKinlay committed
408 409 410
   * @throws NoSuchElementException the Vector is empty
   */
  public synchronized Object lastElement()
Tom Tromey committed
411 412 413 414
  {
    if (elementCount == 0)
      throw new NoSuchElementException();

415
    return elementData[elementCount - 1];
Tom Tromey committed
416 417
  }

Bryce McKinlay committed
418
  /**
419
   * Changes the element at <code>index</code> to be <code>obj</code>
Bryce McKinlay committed
420
   *
421 422
   * @param obj the object to store
   * @param index the position in the Vector to store the object
Bryce McKinlay committed
423
   * @throws ArrayIndexOutOfBoundsException the index is out of range
424
   * @see #set(int, Object)
Bryce McKinlay committed
425
   */
426
  public void setElementAt(Object obj, int index)
Tom Tromey committed
427
  {
428
    set(index, obj);
Tom Tromey committed
429 430
  }

Bryce McKinlay committed
431
  /**
432 433
   * Removes the element at <code>index</code>, and shifts all elements at
   * positions greater than index to their index - 1.
Bryce McKinlay committed
434
   *
435 436 437
   * @param index the index of the element to remove
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size();
   * @see #remove(int)
Bryce McKinlay committed
438
   */
439
  public void removeElementAt(int index)
Tom Tromey committed
440
  {
441
    remove(index);
Tom Tromey committed
442 443
  }

Bryce McKinlay committed
444
  /**
445
   * Inserts a new element into the Vector at <code>index</code>.  Any elements
Bryce McKinlay committed
446 447
   * at or greater than index are shifted up one position.
   *
448 449 450 451
   * @param obj the object to insert
   * @param index the index at which the object is inserted
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt; size()
   * @see #add(int, Object)
Bryce McKinlay committed
452
   */
453
  public synchronized void insertElementAt(Object obj, int index)
Tom Tromey committed
454
  {
455
    checkBoundInclusive(index);
456
    if (elementCount == elementData.length)
457
      ensureCapacity(elementCount + 1);
458
    modCount++;
Bryce McKinlay committed
459
    System.arraycopy(elementData, index, elementData, index + 1,
460 461
                     elementCount - index);
    elementCount++;
Bryce McKinlay committed
462
    elementData[index] = obj;
Tom Tromey committed
463 464
  }

Bryce McKinlay committed
465
  /**
466 467
   * Adds an element to the Vector at the end of the Vector.  The vector
   * is increased by ensureCapacity(size() + 1) if needed.
Bryce McKinlay committed
468
   *
469
   * @param obj the object to add to the Vector
Bryce McKinlay committed
470 471
   */
  public synchronized void addElement(Object obj)
Tom Tromey committed
472
  {
473
    if (elementCount == elementData.length)
474
      ensureCapacity(elementCount + 1);
Bryce McKinlay committed
475 476 477
    modCount++;
    elementData[elementCount++] = obj;
  }
Tom Tromey committed
478

Bryce McKinlay committed
479
  /**
480 481 482
   * Removes the first (the lowestindex) occurance of the given object from
   * the Vector. If such a remove was performed (the object was found), true
   * is returned. If there was no such object, false is returned.
Bryce McKinlay committed
483
   *
484 485 486
   * @param obj the object to remove from the Vector
   * @return true if the Object was in the Vector, false otherwise
   * @see #remove(Object)
Bryce McKinlay committed
487 488 489
   */
  public synchronized boolean removeElement(Object obj)
  {
490 491
    int idx = indexOf(obj, 0);
    if (idx >= 0)
Bryce McKinlay committed
492
      {
493 494
        remove(idx);
        return true;
Bryce McKinlay committed
495 496
      }
    return false;
Tom Tromey committed
497 498
  }

Bryce McKinlay committed
499 500 501
  /**
   * Removes all elements from the Vector.  Note that this does not
   * resize the internal data array.
502 503
   *
   * @see #clear()
Bryce McKinlay committed
504 505
   */
  public synchronized void removeAllElements()
Tom Tromey committed
506
  {
Bryce McKinlay committed
507 508
    if (elementCount == 0)
      return;
Tom Tromey committed
509

510 511
    modCount++;
    Arrays.fill(elementData, 0, elementCount, null);
Bryce McKinlay committed
512
    elementCount = 0;
Tom Tromey committed
513 514
  }

Bryce McKinlay committed
515
  /**
516 517 518 519
   * Creates a new Vector with the same contents as this one. The clone is
   * shallow; elements are not cloned.
   *
   * @return the clone of this vector
Bryce McKinlay committed
520 521
   */
  public synchronized Object clone()
Tom Tromey committed
522
  {
Bryce McKinlay committed
523
    try
Tom Tromey committed
524
      {
525 526 527
        Vector clone = (Vector) super.clone();
        clone.elementData = (Object[]) elementData.clone();
        return clone;
Tom Tromey committed
528
      }
Bryce McKinlay committed
529
    catch (CloneNotSupportedException ex)
Tom Tromey committed
530
      {
531 532
        // Impossible to get here.
        throw new InternalError(ex.toString());
Tom Tromey committed
533 534 535
      }
  }

Bryce McKinlay committed
536 537
  /**
   * Returns an Object array with the contents of this Vector, in the order
538 539 540
   * they are stored within this Vector.  Note that the Object array returned
   * is not the internal data array, and that it holds only the elements
   * within the Vector.  This is similar to creating a new Object[] with the
Bryce McKinlay committed
541 542
   * size of this Vector, then calling Vector.copyInto(yourArray).
   *
543 544
   * @return an Object[] containing the contents of this Vector in order
   * @since 1.2
Bryce McKinlay committed
545 546
   */
  public synchronized Object[] toArray()
Tom Tromey committed
547
  {
Bryce McKinlay committed
548 549 550
    Object[] newArray = new Object[elementCount];
    copyInto(newArray);
    return newArray;
Tom Tromey committed
551 552
  }

Bryce McKinlay committed
553
  /**
554
   * Returns an array containing the contents of this Vector.
Bryce McKinlay committed
555
   * If the provided array is large enough, the contents are copied
556
   * into that array, and a null is placed in the position size().
Bryce McKinlay committed
557
   * In this manner, you can obtain the size of a Vector by the position
558 559 560
   * of the null element, if you know the vector does not itself contain
   * null entries.  If the array is not large enough, reflection is used
   * to create a bigger one of the same runtime type.
Bryce McKinlay committed
561
   *
562 563
   * @param a an array to copy the Vector into if large enough
   * @return an array with the contents of this Vector in order
Bryce McKinlay committed
564
   * @throws ArrayStoreException the runtime type of the provided array
565 566 567
   *         cannot hold the elements of the Vector
   * @throws NullPointerException if <code>a</code> is null
   * @since 1.2
Bryce McKinlay committed
568
   */
569
  public synchronized Object[] toArray(Object[] a)
Tom Tromey committed
570
  {
571 572 573 574 575 576 577
    if (a.length < elementCount)
      a = (Object[]) Array.newInstance(a.getClass().getComponentType(),
                                       elementCount);
    else if (a.length > elementCount)
      a[elementCount] = null;
    System.arraycopy(elementData, 0, a, 0, elementCount);
    return a;
Tom Tromey committed
578 579
  }

Bryce McKinlay committed
580
  /**
581
   * Returns the element at position <code>index</code>.
Bryce McKinlay committed
582 583
   *
   * @param index the position from which an element will be retrieved
584 585 586
   * @return the element at that position
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
   * @since 1.2
Bryce McKinlay committed
587
   */
588
  public Object get(int index)
Tom Tromey committed
589
  {
Bryce McKinlay committed
590
    return elementAt(index);
Tom Tromey committed
591 592
  }

Bryce McKinlay committed
593
  /**
594 595
   * Puts <code>element</code> into the Vector at position <code>index</code>
   * and returns the Object that previously occupied that position.
Bryce McKinlay committed
596
   *
597 598 599 600 601
   * @param index the index within the Vector to place the Object
   * @param element the Object to store in the Vector
   * @return the previous object at the specified index
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
   * @since 1.2
Bryce McKinlay committed
602
   */
603
  public synchronized Object set(int index, Object element)
Bryce McKinlay committed
604
  {
605 606 607 608
    checkBoundExclusive(index);
    Object temp = elementData[index];
    elementData[index] = element;
    return temp;
Bryce McKinlay committed
609
  }
Tom Tromey committed
610

Bryce McKinlay committed
611 612 613
  /**
   * Adds an object to the Vector.
   *
614 615 616
   * @param o the element to add to the Vector
   * @return true, as specified by List
   * @since 1.2
Bryce McKinlay committed
617
   */
618
  public boolean add(Object o)
Bryce McKinlay committed
619 620 621 622
  {
    addElement(o);
    return true;
  }
Tom Tromey committed
623

Bryce McKinlay committed
624
  /**
625 626 627 628 629 630 631 632 633 634 635 636 637
   * Removes the given Object from the Vector.  If it exists, true
   * is returned, if not, false is returned.
   *
   * @param o the object to remove from the Vector
   * @return true if the Object existed in the Vector, false otherwise
   * @since 1.2
   */
  public boolean remove(Object o)
  {
    return removeElement(o);
  }

  /**
Bryce McKinlay committed
638 639 640
   * Adds an object at the specified index.  Elements at or above
   * index are shifted up one position.
   *
641 642 643 644
   * @param index the index at which to add the element
   * @param element the element to add to the Vector
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt; size()
   * @since 1.2
Bryce McKinlay committed
645 646 647 648 649
   */
  public void add(int index, Object element)
  {
    insertElementAt(element, index);
  }
Tom Tromey committed
650

Bryce McKinlay committed
651 652 653
  /**
   * Removes the element at the specified index, and returns it.
   *
654 655 656 657
   * @param index the position from which to remove the element
   * @return the object removed
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
   * @since 1.2
Bryce McKinlay committed
658 659 660
   */
  public synchronized Object remove(int index)
  {
661
    checkBoundExclusive(index);
Bryce McKinlay committed
662
    Object temp = elementData[index];
663 664 665 666 667 668
    modCount++;
    elementCount--;
    if (index < elementCount)
      System.arraycopy(elementData, index + 1, elementData, index,
                       elementCount - index);
    elementData[elementCount] = null;
Bryce McKinlay committed
669 670
    return temp;
  }
Tom Tromey committed
671

Bryce McKinlay committed
672
  /**
673
   * Clears all elements in the Vector and sets its size to 0.
Bryce McKinlay committed
674 675 676 677 678
   */
  public void clear()
  {
    removeAllElements();
  }
Tom Tromey committed
679

680 681 682 683 684 685 686 687
  /**
   * Returns true if this Vector contains all the elements in c.
   *
   * @param c the collection to compare to
   * @return true if this vector contains all elements of c
   * @throws NullPointerException if c is null
   * @since 1.2
   */
Bryce McKinlay committed
688
  public synchronized boolean containsAll(Collection c)
689
  {
690 691
    // Here just for the sychronization.
    return super.containsAll(c);
692
  }
Tom Tromey committed
693

694 695 696 697 698 699 700 701 702 703
  /**
   * Appends all elements of the given collection to the end of this Vector.
   * Behavior is undefined if the collection is modified during this operation
   * (for example, if this == c).
   *
   * @param c the collection to append
   * @return true if this vector changed, in other words c was not empty
   * @throws NullPointerException if c is null
   * @since 1.2
   */
Bryce McKinlay committed
704 705 706 707
  public synchronized boolean addAll(Collection c)
  {
    return addAll(elementCount, c);
  }
708 709 710 711 712 713 714 715 716

  /**
   * Remove from this vector all elements contained in the given collection.
   *
   * @param c the collection to filter out
   * @return true if this vector changed
   * @throws NullPointerException if c is null
   * @since 1.2
   */
Bryce McKinlay committed
717 718
  public synchronized boolean removeAll(Collection c)
  {
719 720 721
    if (c == null)
      throw new NullPointerException();

722 723 724 725 726 727 728 729 730 731 732 733 734 735
    int i;
    int j;
    for (i = 0; i < elementCount; i++)
      if (c.contains(elementData[i]))
        break;
    if (i == elementCount)
      return false;

    modCount++;
    for (j = i++; i < elementCount; i++)
      if (! c.contains(elementData[i]))
        elementData[j++] = elementData[i];
    elementCount -= i - j;
    return true;
Bryce McKinlay committed
736
  }
737 738 739 740 741 742 743 744 745

  /**
   * Retain in this vector only the elements contained in the given collection.
   *
   * @param c the collection to filter by
   * @return true if this vector changed
   * @throws NullPointerException if c is null
   * @since 1.2
   */
Bryce McKinlay committed
746 747
  public synchronized boolean retainAll(Collection c)
  {
748 749 750
    if (c == null)
      throw new NullPointerException();

751 752 753 754 755 756 757 758 759 760 761 762 763 764
    int i;
    int j;
    for (i = 0; i < elementCount; i++)
      if (! c.contains(elementData[i]))
        break;
    if (i == elementCount)
      return false;

    modCount++;
    for (j = i++; i < elementCount; i++)
      if (c.contains(elementData[i]))
        elementData[j++] = elementData[i];
    elementCount -= i - j;
    return true;
Bryce McKinlay committed
765
  }
Tom Tromey committed
766

767 768 769 770 771 772 773 774 775 776 777
  /**
   * Inserts all elements of the given collection at the given index of
   * this Vector. Behavior is undefined if the collection is modified during
   * this operation (for example, if this == c).
   *
   * @param c the collection to append
   * @return true if this vector changed, in other words c was not empty
   * @throws NullPointerException if c is null
   * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt; size()
   * @since 1.2
   */
Bryce McKinlay committed
778 779
  public synchronized boolean addAll(int index, Collection c)
  {
780
    checkBoundInclusive(index);
Bryce McKinlay committed
781 782 783
    Iterator itr = c.iterator();
    int csize = c.size();

784
    modCount++;
Bryce McKinlay committed
785 786 787
    ensureCapacity(elementCount + csize);
    int end = index + csize;
    if (elementCount > 0 && index != elementCount)
788 789
      System.arraycopy(elementData, index,
		       elementData, end, elementCount - index);
Bryce McKinlay committed
790
    elementCount += csize;
791 792 793
    for ( ; index < end; index++)
      elementData[index] = itr.next();
    return (csize > 0);
Bryce McKinlay committed
794
  }
Tom Tromey committed
795

796 797 798 799 800 801 802 803
  /**
   * Compares this to the given object.
   *
   * @param o the object to compare to
   * @return true if the two are equal
   * @since 1.2
   */
  public synchronized boolean equals(Object o)
Bryce McKinlay committed
804
  {
805 806
    // Here just for the sychronization.
    return super.equals(o);
Bryce McKinlay committed
807
  }
Tom Tromey committed
808

809 810 811 812 813 814
  /**
   * Computes the hashcode of this object.
   *
   * @return the hashcode
   * @since 1.2
   */
Bryce McKinlay committed
815 816
  public synchronized int hashCode()
  {
817
    // Here just for the sychronization.
Bryce McKinlay committed
818 819
    return super.hashCode();
  }
Tom Tromey committed
820

Bryce McKinlay committed
821
  /**
822 823
   * Returns a string representation of this Vector in the form
   * "[element0, element1, ... elementN]".
Bryce McKinlay committed
824
   *
825
   * @return the String representation of this Vector
Bryce McKinlay committed
826 827 828
   */
  public synchronized String toString()
  {
829 830
    // Here just for the sychronization.
    return super.toString();
Bryce McKinlay committed
831
  }
Tom Tromey committed
832

Bryce McKinlay committed
833
  /**
834 835 836 837 838 839 840
   * Obtain a List view of a subsection of this list, from fromIndex
   * (inclusive) to toIndex (exclusive). If the two indices are equal, the
   * sublist is empty. The returned list is modifiable, and changes in one
   * reflect in the other. If this list is structurally modified in
   * any way other than through the returned list, the result of any subsequent
   * operations on the returned list is undefined.
   * <p>
Bryce McKinlay committed
841
   *
842 843 844 845 846 847 848 849 850
   * @param fromIndex the index that the returned list should start from
   *        (inclusive)
   * @param toIndex the index that the returned list should go to (exclusive)
   * @return a List backed by a subsection of this vector
   * @throws IndexOutOfBoundsException if fromIndex &lt; 0
   *         || toIndex &gt; size()
   * @throws IllegalArgumentException if fromIndex &gt; toIndex
   * @see ConcurrentModificationException
   * @since 1.2
Bryce McKinlay committed
851
   */
852
  public synchronized List subList(int fromIndex, int toIndex)
Bryce McKinlay committed
853 854
  {
    List sub = super.subList(fromIndex, toIndex);
855 856 857
    // We must specify the correct object to synchronize upon, hence the
    // use of a non-public API
    return new Collections.SynchronizedList(this, sub);
Bryce McKinlay committed
858
  }
859 860 861

  /**
   * Removes a range of elements from this list.
862
   * Does nothing when toIndex is equal to fromIndex.
863 864 865
   *
   * @param fromIndex the index to start deleting from (inclusive)
   * @param toIndex the index to delete up to (exclusive)
866
   * @throws IndexOutOfBoundsException if fromIndex &gt; toIndex
867 868 869 870
   */
  // This does not need to be synchronized, because it is only called through
  // clear() of a sublist, and clear() had already synchronized.
  protected void removeRange(int fromIndex, int toIndex)
Bryce McKinlay committed
871
  {
872 873
    int change = toIndex - fromIndex;
    if (change > 0)
Bryce McKinlay committed
874
      {
875 876 877 878
        modCount++;
        System.arraycopy(elementData, toIndex, elementData, fromIndex,
                         elementCount - toIndex);
        int save = elementCount;
879
        elementCount -= change;
880
        Arrays.fill(elementData, elementCount, save, null);
Bryce McKinlay committed
881
      }
882 883
    else if (change < 0)
      throw new IndexOutOfBoundsException();
Bryce McKinlay committed
884
  }
885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914

  /**
   * Checks that the index is in the range of possible elements (inclusive).
   *
   * @param index the index to check
   * @throws ArrayIndexOutOfBoundsException if index &gt; size
   */
  private void checkBoundInclusive(int index)
  {
    // Implementation note: we do not check for negative ranges here, since
    // use of a negative index will cause an ArrayIndexOutOfBoundsException
    // with no effort on our part.
    if (index > elementCount)
      throw new ArrayIndexOutOfBoundsException(index + " > " + elementCount);
  }

  /**
   * Checks that the index is in the range of existing elements (exclusive).
   *
   * @param index the index to check
   * @throws ArrayIndexOutOfBoundsException if index &gt;= size
   */
  private void checkBoundExclusive(int index)
  {
    // Implementation note: we do not check for negative ranges here, since
    // use of a negative index will cause an ArrayIndexOutOfBoundsException
    // with no effort on our part.
    if (index >= elementCount)
      throw new ArrayIndexOutOfBoundsException(index + " >= " + elementCount);
  }
Tom Tromey committed
915
}