Source for java.util.Vector

   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 <code>Vector</code> 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.<p>
  52:  *
  53:  * Vectors try to mantain efficiency in growing by having a
  54:  * <code>capacityIncrement</code> that can be specified at instantiation.
  55:  * When a Vector can no longer hold a new Object, it grows by the amount
  56:  * in <code>capacityIncrement</code>. If this value is 0, the vector doubles in
  57:  * size.<p>
  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.<p>
  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 (ebb9@email.byu.edu)
  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<T> extends AbstractList<T>
  86:   implements List<T>, 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 Object[] 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 &lt;= 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<? extends T> c)
 134:   {
 135:     elementCount = c.size();
 136:     elementData = c.toArray(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 &lt; 0
 147:    */
 148:   public Vector(int initialCapacity, int capacityIncrement)
 149:   {
 150:     if (initialCapacity < 0)
 151:       throw new IllegalArgumentException();
 152:     elementData = 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 &lt; 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 <code>minCapacity</code> elements can fit within this Vector.
 202:    * If <code>elementData</code> is too small, it is expanded as follows:
 203:    * If the <code>elementCount + capacityIncrement</code> is adequate, that
 204:    * is the new size. If <code>capacityIncrement</code> is non-zero, the
 205:    * candidate size is double the current. If that is not enough, the new
 206:    * size is <code>minCapacity</code>.
 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<T> elements()
 288:   {
 289:     return new Enumeration<T>()
 290:     {
 291:       private int i = 0;
 292: 
 293:       public boolean hasMoreElements()
 294:       {
 295:         return i < elementCount;
 296:       }
 297: 
 298:       @SuppressWarnings("unchecked")
 299:       public T nextElement()
 300:       {
 301:         if (i >= elementCount)
 302:           throw new NoSuchElementException();
 303:         return (T) elementData[i++];
 304:       }
 305:     };
 306:   }
 307: 
 308:   /**
 309:    * Returns true when <code>elem</code> is contained in this Vector.
 310:    *
 311:    * @param elem the element to check
 312:    * @return true if the object is contained in this Vector, false otherwise
 313:    */
 314:   public boolean contains(Object elem)
 315:   {
 316:     return indexOf(elem, 0) >= 0;
 317:   }
 318: 
 319:   /**
 320:    * Returns the first occurrence of <code>elem</code> in the Vector, or -1 if
 321:    * <code>elem</code> is not found.
 322:    *
 323:    * @param elem the object to search for
 324:    * @return the index of the first occurrence, or -1 if not found
 325:    */
 326:   public int indexOf(Object elem)
 327:   {
 328:     return indexOf(elem, 0);
 329:   }
 330: 
 331:   /**
 332:    * Searches the vector starting at <code>index</code> for object
 333:    * <code>elem</code> and returns the index of the first occurrence of this
 334:    * Object.  If the object is not found, or index is larger than the size
 335:    * of the vector, -1 is returned.
 336:    *
 337:    * @param e the Object to search for
 338:    * @param index start searching at this index
 339:    * @return the index of the next occurrence, or -1 if it is not found
 340:    * @throws IndexOutOfBoundsException if index &lt; 0
 341:    */
 342:   public synchronized int indexOf(Object e, int index)
 343:   {
 344:     for (int i = index; i < elementCount; i++)
 345:       if (equals(e, elementData[i]))
 346:         return i;
 347:     return -1;
 348:   }
 349: 
 350:   /**
 351:    * Returns the last index of <code>elem</code> within this Vector, or -1
 352:    * if the object is not within the Vector.
 353:    *
 354:    * @param elem the object to search for
 355:    * @return the last index of the object, or -1 if not found
 356:    */
 357:   public int lastIndexOf(Object elem)
 358:   {
 359:     return lastIndexOf(elem, elementCount - 1);
 360:   }
 361: 
 362:   /**
 363:    * Returns the index of the first occurrence of <code>elem</code>, when
 364:    * searching backwards from <code>index</code>.  If the object does not
 365:    * occur in this Vector, or index is less than 0, -1 is returned.
 366:    *
 367:    * @param e the object to search for
 368:    * @param index the index to start searching in reverse from
 369:    * @return the index of the Object if found, -1 otherwise
 370:    * @throws IndexOutOfBoundsException if index &gt;= size()
 371:    */
 372:   public synchronized int lastIndexOf(Object e, int index)
 373:   {
 374:     checkBoundExclusive(index);
 375:     for (int i = index; i >= 0; i--)
 376:       if (equals(e, elementData[i]))
 377:         return i;
 378:     return -1;
 379:   }
 380: 
 381:   /**
 382:    * Returns the Object stored at <code>index</code>.
 383:    *
 384:    * @param index the index of the Object to retrieve
 385:    * @return the object at <code>index</code>
 386:    * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
 387:    * @see #get(int)
 388:    */
 389:   @SuppressWarnings("unchecked")
 390:   public synchronized T elementAt(int index)
 391:   {
 392:     checkBoundExclusive(index);
 393:     return (T) elementData[index];
 394:   }
 395: 
 396:   /**
 397:    * Returns the first element (index 0) in the Vector.
 398:    *
 399:    * @return the first Object in the Vector
 400:    * @throws NoSuchElementException the Vector is empty
 401:    */
 402:   @SuppressWarnings("unchecked")
 403:   public synchronized T firstElement()
 404:   {
 405:     if (elementCount == 0)
 406:       throw new NoSuchElementException();
 407: 
 408:     return (T) elementData[0];
 409:   }
 410: 
 411:   /**
 412:    * Returns the last element in the Vector.
 413:    *
 414:    * @return the last Object in the Vector
 415:    * @throws NoSuchElementException the Vector is empty
 416:    */
 417:   @SuppressWarnings("unchecked")
 418:   public synchronized T lastElement()
 419:   {
 420:     if (elementCount == 0)
 421:       throw new NoSuchElementException();
 422: 
 423:     return (T) elementData[elementCount - 1];
 424:   }
 425: 
 426:   /**
 427:    * Changes the element at <code>index</code> to be <code>obj</code>
 428:    *
 429:    * @param obj the object to store
 430:    * @param index the position in the Vector to store the object
 431:    * @throws ArrayIndexOutOfBoundsException the index is out of range
 432:    * @see #set(int, Object)
 433:    */
 434:   public void setElementAt(T obj, int index)
 435:   {
 436:     set(index, obj);
 437:   }
 438: 
 439:   /**
 440:    * Removes the element at <code>index</code>, and shifts all elements at
 441:    * positions greater than index to their index - 1.
 442:    *
 443:    * @param index the index of the element to remove
 444:    * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size();
 445:    * @see #remove(int)
 446:    */
 447:   public void removeElementAt(int index)
 448:   {
 449:     remove(index);
 450:   }
 451: 
 452:   /**
 453:    * Inserts a new element into the Vector at <code>index</code>.  Any elements
 454:    * at or greater than index are shifted up one position.
 455:    *
 456:    * @param obj the object to insert
 457:    * @param index the index at which the object is inserted
 458:    * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt; size()
 459:    * @see #add(int, Object)
 460:    */
 461:   public synchronized void insertElementAt(T obj, int index)
 462:   {
 463:     checkBoundInclusive(index);
 464:     if (elementCount == elementData.length)
 465:       ensureCapacity(elementCount + 1);
 466:     modCount++;
 467:     System.arraycopy(elementData, index, elementData, index + 1,
 468:                      elementCount - index);
 469:     elementCount++;
 470:     elementData[index] = obj;
 471:   }
 472: 
 473:   /**
 474:    * Adds an element to the Vector at the end of the Vector.  The vector
 475:    * is increased by ensureCapacity(size() + 1) if needed.
 476:    *
 477:    * @param obj the object to add to the Vector
 478:    */
 479:   public synchronized void addElement(T obj)
 480:   {
 481:     if (elementCount == elementData.length)
 482:       ensureCapacity(elementCount + 1);
 483:     modCount++;
 484:     elementData[elementCount++] = obj;
 485:   }
 486: 
 487:   /**
 488:    * Removes the first (the lowest index) occurrence of the given object from
 489:    * the Vector. If such a remove was performed (the object was found), true
 490:    * is returned. If there was no such object, false is returned.
 491:    *
 492:    * @param obj the object to remove from the Vector
 493:    * @return true if the Object was in the Vector, false otherwise
 494:    * @see #remove(Object)
 495:    */
 496:   public synchronized boolean removeElement(Object obj)
 497:   {
 498:     int idx = indexOf(obj, 0);
 499:     if (idx >= 0)
 500:       {
 501:         remove(idx);
 502:         return true;
 503:       }
 504:     return false;
 505:   }
 506: 
 507:   /**
 508:    * Removes all elements from the Vector.  Note that this does not
 509:    * resize the internal data array.
 510:    *
 511:    * @see #clear()
 512:    */
 513:   public synchronized void removeAllElements()
 514:   {
 515:     if (elementCount == 0)
 516:       return;
 517: 
 518:     modCount++;
 519:     Arrays.fill(elementData, 0, elementCount, null);
 520:     elementCount = 0;
 521:   }
 522: 
 523:   /**
 524:    * Creates a new Vector with the same contents as this one. The clone is
 525:    * shallow; elements are not cloned.
 526:    *
 527:    * @return the clone of this vector
 528:    */
 529:   public synchronized Object clone()
 530:   {
 531:     try
 532:       {
 533:         Vector clone = (Vector) super.clone();
 534:         clone.elementData = (Object[]) elementData.clone();
 535:         return clone;
 536:       }
 537:     catch (CloneNotSupportedException ex)
 538:       {
 539:         // Impossible to get here.
 540:         throw new InternalError(ex.toString());
 541:       }
 542:   }
 543: 
 544:   /**
 545:    * Returns an Object array with the contents of this Vector, in the order
 546:    * they are stored within this Vector.  Note that the Object array returned
 547:    * is not the internal data array, and that it holds only the elements
 548:    * within the Vector.  This is similar to creating a new Object[] with the
 549:    * size of this Vector, then calling Vector.copyInto(yourArray).
 550:    *
 551:    * @return an Object[] containing the contents of this Vector in order
 552:    * @since 1.2
 553:    */
 554:   public synchronized Object[] toArray()
 555:   {
 556:     Object[] newArray = new Object[elementCount];
 557:     copyInto(newArray);
 558:     return newArray;
 559:   }
 560: 
 561:   /**
 562:    * Returns an array containing the contents of this Vector.
 563:    * If the provided array is large enough, the contents are copied
 564:    * into that array, and a null is placed in the position size().
 565:    * In this manner, you can obtain the size of a Vector by the position
 566:    * of the null element, if you know the vector does not itself contain
 567:    * null entries.  If the array is not large enough, reflection is used
 568:    * to create a bigger one of the same runtime type.
 569:    *
 570:    * @param a an array to copy the Vector into if large enough
 571:    * @return an array with the contents of this Vector in order
 572:    * @throws ArrayStoreException the runtime type of the provided array
 573:    *         cannot hold the elements of the Vector
 574:    * @throws NullPointerException if <code>a</code> is null
 575:    * @since 1.2
 576:    */
 577:   public synchronized <S> S[] toArray(S[] a)
 578:   {
 579:     if (a.length < elementCount)
 580:       a = (S[]) Array.newInstance(a.getClass().getComponentType(),
 581:                                   elementCount);
 582:     else if (a.length > elementCount)
 583:       a[elementCount] = null;
 584:     System.arraycopy(elementData, 0, a, 0, elementCount);
 585:     return a;
 586:   }
 587: 
 588:   /**
 589:    * Returns the element at position <code>index</code>.
 590:    *
 591:    * @param index the position from which an element will be retrieved
 592:    * @return the element at that position
 593:    * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
 594:    * @since 1.2
 595:    */
 596:   public T get(int index)
 597:   {
 598:     return elementAt(index);
 599:   }
 600: 
 601:   /**
 602:    * Puts <code>element</code> into the Vector at position <code>index</code>
 603:    * and returns the Object that previously occupied that position.
 604:    *
 605:    * @param index the index within the Vector to place the Object
 606:    * @param element the Object to store in the Vector
 607:    * @return the previous object at the specified index
 608:    * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
 609:    * @since 1.2
 610:    */
 611:   @SuppressWarnings("unchecked")
 612:   public synchronized T set(int index, T element)
 613:   {
 614:     checkBoundExclusive(index);
 615:     T temp = (T) elementData[index];
 616:     elementData[index] = element;
 617:     return temp;
 618:   }
 619: 
 620:   /**
 621:    * Adds an object to the Vector.
 622:    *
 623:    * @param o the element to add to the Vector
 624:    * @return true, as specified by List
 625:    * @since 1.2
 626:    */
 627:   public boolean add(T o)
 628:   {
 629:     addElement(o);
 630:     return true;
 631:   }
 632: 
 633:   /**
 634:    * Removes the given Object from the Vector.  If it exists, true
 635:    * is returned, if not, false is returned.
 636:    *
 637:    * @param o the object to remove from the Vector
 638:    * @return true if the Object existed in the Vector, false otherwise
 639:    * @since 1.2
 640:    */
 641:   public boolean remove(Object o)
 642:   {
 643:     return removeElement(o);
 644:   }
 645: 
 646:   /**
 647:    * Adds an object at the specified index.  Elements at or above
 648:    * index are shifted up one position.
 649:    *
 650:    * @param index the index at which to add the element
 651:    * @param element the element to add to the Vector
 652:    * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt; size()
 653:    * @since 1.2
 654:    */
 655:   public void add(int index, T element)
 656:   {
 657:     insertElementAt(element, index);
 658:   }
 659: 
 660:   /**
 661:    * Removes the element at the specified index, and returns it.
 662:    *
 663:    * @param index the position from which to remove the element
 664:    * @return the object removed
 665:    * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt;= size()
 666:    * @since 1.2
 667:    */
 668:   @SuppressWarnings("unchecked")
 669:   public synchronized T remove(int index)
 670:   {
 671:     checkBoundExclusive(index);
 672:     T temp = (T) elementData[index];
 673:     modCount++;
 674:     elementCount--;
 675:     if (index < elementCount)
 676:       System.arraycopy(elementData, index + 1, elementData, index,
 677:                        elementCount - index);
 678:     elementData[elementCount] = null;
 679:     return temp;
 680:   }
 681: 
 682:   /**
 683:    * Clears all elements in the Vector and sets its size to 0.
 684:    */
 685:   public void clear()
 686:   {
 687:     removeAllElements();
 688:   }
 689: 
 690:   /**
 691:    * Returns true if this Vector contains all the elements in c.
 692:    *
 693:    * @param c the collection to compare to
 694:    * @return true if this vector contains all elements of c
 695:    * @throws NullPointerException if c is null
 696:    * @since 1.2
 697:    */
 698:   public synchronized boolean containsAll(Collection<?> c)
 699:   {
 700:     // Here just for the sychronization.
 701:     return super.containsAll(c);
 702:   }
 703: 
 704:   /**
 705:    * Appends all elements of the given collection to the end of this Vector.
 706:    * Behavior is undefined if the collection is modified during this operation
 707:    * (for example, if this == c).
 708:    *
 709:    * @param c the collection to append
 710:    * @return true if this vector changed, in other words c was not empty
 711:    * @throws NullPointerException if c is null
 712:    * @since 1.2
 713:    */
 714:   public synchronized boolean addAll(Collection<? extends T> c)
 715:   {
 716:     return addAll(elementCount, c);
 717:   }
 718: 
 719:   /**
 720:    * Remove from this vector all elements contained in the given collection.
 721:    *
 722:    * @param c the collection to filter out
 723:    * @return true if this vector changed
 724:    * @throws NullPointerException if c is null
 725:    * @since 1.2
 726:    */
 727:   public synchronized boolean removeAll(Collection<?> c)
 728:   {
 729:     // The NullPointerException is thrown implicitly when the Vector
 730:     // is not empty and c is null. The RI allows null arguments when
 731:     // the vector is empty. See Mauve test:
 732:     // gnu/testlet/java/util/Vector/removeAll.java
 733: 
 734:     int i;
 735:     int j;
 736:     for (i = 0; i < elementCount; i++)
 737:       if (c.contains(elementData[i]))
 738:         break;
 739:     if (i == elementCount)
 740:       return false;
 741: 
 742:     modCount++;
 743:     for (j = i++; i < elementCount; i++)
 744:       if (! c.contains(elementData[i]))
 745:         elementData[j++] = elementData[i];
 746:     elementCount -= i - j;
 747:     return true;
 748:   }
 749: 
 750:   /**
 751:    * Retain in this vector only the elements contained in the given collection.
 752:    *
 753:    * @param c the collection to filter by
 754:    * @return true if this vector changed
 755:    * @throws NullPointerException if c is null
 756:    * @since 1.2
 757:    */
 758:   public synchronized boolean retainAll(Collection<?> c)
 759:   {
 760:     // The NullPointerException is thrown implicitly when the Vector
 761:     // is not empty and c is null. The RI allows null arguments when
 762:     // the vector is empty. See Mauve test:
 763:     // gnu/testlet/java/util/Vector/retainAll.java
 764: 
 765:     int i;
 766:     int j;
 767:     for (i = 0; i < elementCount; i++)
 768:       if (! c.contains(elementData[i]))
 769:         break;
 770:     if (i == elementCount)
 771:       return false;
 772: 
 773:     modCount++;
 774:     for (j = i++; i < elementCount; i++)
 775:       if (c.contains(elementData[i]))
 776:         elementData[j++] = elementData[i];
 777:     elementCount -= i - j;
 778:     return true;
 779:   }
 780: 
 781:   /**
 782:    * Inserts all elements of the given collection at the given index of
 783:    * this Vector. Behavior is undefined if the collection is modified during
 784:    * this operation (for example, if this == c).
 785:    *
 786:    * @param c the collection to append
 787:    * @return true if this vector changed, in other words c was not empty
 788:    * @throws NullPointerException if c is null
 789:    * @throws ArrayIndexOutOfBoundsException index &lt; 0 || index &gt; size()
 790:    * @since 1.2
 791:    */
 792:   public synchronized boolean addAll(int index, Collection<? extends T> c)
 793:   {
 794:     checkBoundInclusive(index);
 795:     Iterator<? extends T> itr = c.iterator();
 796:     int csize = c.size();
 797: 
 798:     modCount++;
 799:     ensureCapacity(elementCount + csize);
 800:     int end = index + csize;
 801:     if (elementCount > 0 && index != elementCount)
 802:       System.arraycopy(elementData, index,
 803:                        elementData, end, elementCount - index);
 804:     elementCount += csize;
 805:     for ( ; index < end; index++)
 806:       elementData[index] = itr.next();
 807:     return (csize > 0);
 808:   }
 809: 
 810:   /**
 811:    * Compares this to the given object.
 812:    *
 813:    * @param o the object to compare to
 814:    * @return true if the two are equal
 815:    * @since 1.2
 816:    */
 817:   public synchronized boolean equals(Object o)
 818:   {
 819:     // Here just for the sychronization.
 820:     return super.equals(o);
 821:   }
 822: 
 823:   /**
 824:    * Computes the hashcode of this object.
 825:    *
 826:    * @return the hashcode
 827:    * @since 1.2
 828:    */
 829:   public synchronized int hashCode()
 830:   {
 831:     // Here just for the sychronization.
 832:     return super.hashCode();
 833:   }
 834: 
 835:   /**
 836:    * Returns a string representation of this Vector in the form
 837:    * "[element0, element1, ... elementN]".
 838:    *
 839:    * @return the String representation of this Vector
 840:    */
 841:   public synchronized String toString()
 842:   {
 843:     // Here just for the sychronization.
 844:     return super.toString();
 845:   }
 846: 
 847:   /**
 848:    * Obtain a List view of a subsection of this list, from fromIndex
 849:    * (inclusive) to toIndex (exclusive). If the two indices are equal, the
 850:    * sublist is empty. The returned list is modifiable, and changes in one
 851:    * reflect in the other. If this list is structurally modified in
 852:    * any way other than through the returned list, the result of any subsequent
 853:    * operations on the returned list is undefined.
 854:    * <p>
 855:    *
 856:    * @param fromIndex the index that the returned list should start from
 857:    *        (inclusive)
 858:    * @param toIndex the index that the returned list should go to (exclusive)
 859:    * @return a List backed by a subsection of this vector
 860:    * @throws IndexOutOfBoundsException if fromIndex &lt; 0
 861:    *         || toIndex &gt; size()
 862:    * @throws IllegalArgumentException if fromIndex &gt; toIndex
 863:    * @see ConcurrentModificationException
 864:    * @since 1.2
 865:    */
 866:   public synchronized List<T> subList(int fromIndex, int toIndex)
 867:   {
 868:     List<T> sub = super.subList(fromIndex, toIndex);
 869:     // We must specify the correct object to synchronize upon, hence the
 870:     // use of a non-public API
 871:     return new Collections.SynchronizedList<T>(this, sub);
 872:   }
 873: 
 874:   /**
 875:    * Removes a range of elements from this list.
 876:    * Does nothing when toIndex is equal to fromIndex.
 877:    *
 878:    * @param fromIndex the index to start deleting from (inclusive)
 879:    * @param toIndex the index to delete up to (exclusive)
 880:    * @throws IndexOutOfBoundsException if fromIndex &gt; toIndex
 881:    */
 882:   // This does not need to be synchronized, because it is only called through
 883:   // clear() of a sublist, and clear() had already synchronized.
 884:   protected void removeRange(int fromIndex, int toIndex)
 885:   {
 886:     int change = toIndex - fromIndex;
 887:     if (change > 0)
 888:       {
 889:         modCount++;
 890:         System.arraycopy(elementData, toIndex, elementData, fromIndex,
 891:                          elementCount - toIndex);
 892:         int save = elementCount;
 893:         elementCount -= change;
 894:         Arrays.fill(elementData, elementCount, save, null);
 895:       }
 896:     else if (change < 0)
 897:       throw new IndexOutOfBoundsException();
 898:   }
 899: 
 900:   /**
 901:    * Checks that the index is in the range of possible elements (inclusive).
 902:    *
 903:    * @param index the index to check
 904:    * @throws ArrayIndexOutOfBoundsException if index &gt; size
 905:    */
 906:   private void checkBoundInclusive(int index)
 907:   {
 908:     // Implementation note: we do not check for negative ranges here, since
 909:     // use of a negative index will cause an ArrayIndexOutOfBoundsException
 910:     // with no effort on our part.
 911:     if (index > elementCount)
 912:       raiseBoundsError(index, " > ");
 913:   }
 914: 
 915:   /**
 916:    * Checks that the index is in the range of existing elements (exclusive).
 917:    *
 918:    * @param index the index to check
 919:    * @throws ArrayIndexOutOfBoundsException if index &gt;= size
 920:    */
 921:   private void checkBoundExclusive(int index)
 922:   {
 923:     // Implementation note: we do not check for negative ranges here, since
 924:     // use of a negative index will cause an ArrayIndexOutOfBoundsException
 925:     // with no effort on our part.
 926:     if (index >= elementCount)
 927:       raiseBoundsError(index, " >= ");
 928:   }
 929: 
 930:   /**
 931:    * Raise the ArrayIndexOfOutBoundsException.
 932:    *
 933:    * @param index the index of the access
 934:    * @param operator the operator to include in the error message
 935:    * @throws IndexOutOfBoundsException unconditionally
 936:    */
 937:   private void raiseBoundsError(int index, String operator)
 938:   {
 939:     // Implementaion note: put in a separate method to make the JITs job easier
 940:     // (separate common from uncommon code at method boundaries when trivial to
 941:     // do so).
 942:     throw new ArrayIndexOutOfBoundsException(index + operator + elementCount);
 943:   }
 944: 
 945:   /**
 946:    * Serializes this object to the given stream.
 947:    *
 948:    * @param s the stream to write to
 949:    * @throws IOException if the underlying stream fails
 950:    * @serialData just calls default write function
 951:    */
 952:   private synchronized void writeObject(ObjectOutputStream s)
 953:     throws IOException
 954:   {
 955:     s.defaultWriteObject();
 956:   }
 957: 
 958: }