Frames | No Frames |
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 <= 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 < 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 < 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 < 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 >= 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 < 0 || index >= 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 < 0 || index >= 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 < 0 || index > 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 < 0 || index >= 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 < 0 || index >= 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 < 0 || index > 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 < 0 || index >= 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 < 0 || index > 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 < 0 861: * || toIndex > size() 862: * @throws IllegalArgumentException if fromIndex > 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 > 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 > 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 >= 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: }