001/* Vector.java -- Class that provides growable arrays. 002 Copyright (C) 1998, 1999, 2000, 2001, 2004, 2005, 2006, 003 Free Software Foundation, Inc. 004 005This file is part of GNU Classpath. 006 007GNU Classpath is free software; you can redistribute it and/or modify 008it under the terms of the GNU General Public License as published by 009the Free Software Foundation; either version 2, or (at your option) 010any later version. 011 012GNU Classpath is distributed in the hope that it will be useful, but 013WITHOUT ANY WARRANTY; without even the implied warranty of 014MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015General Public License for more details. 016 017You should have received a copy of the GNU General Public License 018along with GNU Classpath; see the file COPYING. If not, write to the 019Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02002110-1301 USA. 021 022Linking this library statically or dynamically with other modules is 023making a combined work based on this library. Thus, the terms and 024conditions of the GNU General Public License cover the whole 025combination. 026 027As a special exception, the copyright holders of this library give you 028permission to link this library with independent modules to produce an 029executable, regardless of the license terms of these independent 030modules, and to copy and distribute the resulting executable under 031terms of your choice, provided that you also meet, for each linked 032independent module, the terms and conditions of the license of that 033module. An independent module is a module which is not derived from 034or based on this library. If you modify this library, you may extend 035this exception to your version of the library, but you are not 036obligated to do so. If you do not wish to do so, delete this 037exception statement from your version. */ 038 039 040package java.util; 041 042import java.io.IOException; 043import java.io.ObjectOutputStream; 044import java.io.Serializable; 045import java.lang.reflect.Array; 046 047/** 048 * The <code>Vector</code> classes implements growable arrays of Objects. 049 * You can access elements in a Vector with an index, just as you 050 * can in a built in array, but Vectors can grow and shrink to accommodate 051 * more or fewer objects.<p> 052 * 053 * Vectors try to mantain efficiency in growing by having a 054 * <code>capacityIncrement</code> that can be specified at instantiation. 055 * When a Vector can no longer hold a new Object, it grows by the amount 056 * in <code>capacityIncrement</code>. If this value is 0, the vector doubles in 057 * size.<p> 058 * 059 * Vector implements the JDK 1.2 List interface, and is therefore a fully 060 * compliant Collection object. The iterators are fail-fast - if external 061 * code structurally modifies the vector, any operation on the iterator will 062 * then throw a {@link ConcurrentModificationException}. The Vector class is 063 * fully synchronized, but the iterators are not. So, when iterating over a 064 * vector, be sure to synchronize on the vector itself. If you don't want the 065 * expense of synchronization, use ArrayList instead. On the other hand, the 066 * Enumeration of elements() is not thread-safe, nor is it fail-fast; so it 067 * can lead to undefined behavior even in a single thread if you modify the 068 * vector during iteration.<p> 069 * 070 * Note: Some methods, especially those specified by List, specify throwing 071 * {@link IndexOutOfBoundsException}, but it is easier to implement by 072 * throwing the subclass {@link ArrayIndexOutOfBoundsException}. Others 073 * directly specify this subclass. 074 * 075 * @author Scott G. Miller 076 * @author Bryce McKinlay 077 * @author Eric Blake (ebb9@email.byu.edu) 078 * @see Collection 079 * @see List 080 * @see ArrayList 081 * @see LinkedList 082 * @since 1.0 083 * @status updated to 1.4 084 */ 085public class Vector<T> extends AbstractList<T> 086 implements List<T>, RandomAccess, Cloneable, Serializable 087{ 088 /** 089 * Compatible with JDK 1.0+. 090 */ 091 private static final long serialVersionUID = -2767605614048989439L; 092 093 /** 094 * The internal array used to hold members of a Vector. The elements are 095 * in positions 0 through elementCount - 1, and all remaining slots are null. 096 * @serial the elements 097 */ 098 protected Object[] elementData; 099 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}