Source for java.util.Vector

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