1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18 package java.util; 19 20 import java.io.IOException; 21 import java.io.ObjectOutputStream; 22 import java.io.Serializable; 23 import java.lang.reflect.Array; 24 25 /** 26 * Vector is a variable size contiguous indexable array of objects. The size of 27 * the vector is the number of objects it contains. The capacity of the vector 28 * is the number of objects it can hold. 29 * <p> 30 * Objects may be inserted at any position up to the size of the vector, thus 31 * increasing the size of the vector. Objects at any position in the vector may 32 * be removed, thus shrinking the size of the Vector. Objects at any position in 33 * the Vector may be replaced, which does not affect the vector's size. 34 * <p> 35 * The capacity of a vector may be specified when the vector is created. If the 36 * capacity of the vector is exceeded, the capacity is increased (doubled by 37 * default). 38 * 39 * @see java.lang.StringBuffer 40 */ 41 public class Vector<E> extends AbstractList<E> implements List<E>, 42 RandomAccess, Cloneable, Serializable { 43 44 private static final long serialVersionUID = -2767605614048989439L; 45 46 /** 47 * The number of elements or the size of the vector. 48 */ 49 protected int elementCount; 50 51 /** 52 * The elements of the vector. 53 */ 54 protected Object[] elementData; 55 56 /** 57 * How many elements should be added to the vector when it is detected that 58 * it needs to grow to accommodate extra entries. If this value is zero or 59 * negative the size will be doubled if an increase is needed. 60 */ 61 protected int capacityIncrement; 62 63 private static final int DEFAULT_SIZE = 10; 64 65 /** 66 * Constructs a new vector using the default capacity. 67 */ Vector()68 public Vector() { 69 this(DEFAULT_SIZE, 0); 70 } 71 72 /** 73 * Constructs a new vector using the specified capacity. 74 * 75 * @param capacity 76 * the initial capacity of the new vector. 77 * @throws IllegalArgumentException 78 * if {@code capacity} is negative. 79 */ Vector(int capacity)80 public Vector(int capacity) { 81 this(capacity, 0); 82 } 83 84 /** 85 * Constructs a new vector using the specified capacity and capacity 86 * increment. 87 * 88 * @param capacity 89 * the initial capacity of the new vector. 90 * @param capacityIncrement 91 * the amount to increase the capacity when this vector is full. 92 * @throws IllegalArgumentException 93 * if {@code capacity} is negative. 94 */ Vector(int capacity, int capacityIncrement)95 public Vector(int capacity, int capacityIncrement) { 96 if (capacity < 0) { 97 throw new IllegalArgumentException(); 98 } 99 elementData = newElementArray(capacity); 100 elementCount = 0; 101 this.capacityIncrement = capacityIncrement; 102 } 103 104 /** 105 * Constructs a new instance of {@code Vector} containing the elements in 106 * {@code collection}. The order of the elements in the new {@code Vector} 107 * is dependent on the iteration order of the seed collection. 108 * 109 * @param collection 110 * the collection of elements to add. 111 */ Vector(Collection<? extends E> collection)112 public Vector(Collection<? extends E> collection) { 113 this(collection.size(), 0); 114 Iterator<? extends E> it = collection.iterator(); 115 while (it.hasNext()) { 116 elementData[elementCount++] = it.next(); 117 } 118 } 119 120 @SuppressWarnings("unchecked") newElementArray(int size)121 private E[] newElementArray(int size) { 122 return (E[]) new Object[size]; 123 } 124 125 /** 126 * Adds the specified object into this vector at the specified location. The 127 * object is inserted before any element with the same or a higher index 128 * increasing their index by 1. If the location is equal to the size of this 129 * vector, the object is added at the end. 130 * 131 * @param location 132 * the index at which to insert the element. 133 * @param object 134 * the object to insert in this vector. 135 * @throws ArrayIndexOutOfBoundsException 136 * if {@code location < 0 || location > size()}. 137 * @see #addElement 138 * @see #size 139 */ 140 @Override add(int location, E object)141 public void add(int location, E object) { 142 insertElementAt(object, location); 143 } 144 145 /** 146 * Adds the specified object at the end of this vector. 147 * 148 * @param object 149 * the object to add to the vector. 150 * @return {@code true} 151 */ 152 @Override add(E object)153 public synchronized boolean add(E object) { 154 if (elementCount == elementData.length) { 155 growByOne(); 156 } 157 elementData[elementCount++] = object; 158 modCount++; 159 return true; 160 } 161 162 /** 163 * Inserts the objects in the specified collection at the specified location 164 * in this vector. The objects are inserted in the order in which they are 165 * returned from the Collection iterator. The elements with an index equal 166 * or higher than {@code location} have their index increased by the size of 167 * the added collection. 168 * 169 * @param location 170 * the location to insert the objects. 171 * @param collection 172 * the collection of objects. 173 * @return {@code true} if this vector is modified, {@code false} otherwise. 174 * @throws ArrayIndexOutOfBoundsException 175 * if {@code location < 0} or {@code location > size()}. 176 */ 177 @Override addAll(int location, Collection<? extends E> collection)178 public synchronized boolean addAll(int location, 179 Collection<? extends E> collection) { 180 if (0 <= location && location <= elementCount) { 181 int size = collection.size(); 182 if (size == 0) { 183 return false; 184 } 185 int required = size - (elementData.length - elementCount); 186 if (required > 0) { 187 growBy(required); 188 } 189 int count = elementCount - location; 190 if (count > 0) { 191 System.arraycopy(elementData, location, elementData, location 192 + size, count); 193 } 194 Iterator<? extends E> it = collection.iterator(); 195 while (it.hasNext()) { 196 elementData[location++] = it.next(); 197 } 198 elementCount += size; 199 modCount++; 200 return true; 201 } 202 throw new ArrayIndexOutOfBoundsException(location); 203 } 204 205 /** 206 * Adds the objects in the specified collection to the end of this vector. 207 * 208 * @param collection 209 * the collection of objects. 210 * @return {@code true} if this vector is modified, {@code false} otherwise. 211 */ 212 @Override addAll(Collection<? extends E> collection)213 public synchronized boolean addAll(Collection<? extends E> collection) { 214 return addAll(elementCount, collection); 215 } 216 217 /** 218 * Adds the specified object at the end of this vector. 219 * 220 * @param object 221 * the object to add to the vector. 222 */ addElement(E object)223 public synchronized void addElement(E object) { 224 if (elementCount == elementData.length) { 225 growByOne(); 226 } 227 elementData[elementCount++] = object; 228 modCount++; 229 } 230 231 /** 232 * Returns the number of elements this vector can hold without growing. 233 * 234 * @return the capacity of this vector. 235 * @see #ensureCapacity 236 * @see #size 237 */ capacity()238 public synchronized int capacity() { 239 return elementData.length; 240 } 241 242 /** 243 * Removes all elements from this vector, leaving it empty. 244 * 245 * @see #isEmpty 246 * @see #size 247 */ 248 @Override clear()249 public void clear() { 250 removeAllElements(); 251 } 252 253 /** 254 * Returns a new vector with the same elements, size, capacity and capacity 255 * increment as this vector. 256 * 257 * @return a shallow copy of this vector. 258 * @see java.lang.Cloneable 259 */ 260 @Override 261 @SuppressWarnings("unchecked") clone()262 public synchronized Object clone() { 263 try { 264 Vector<E> vector = (Vector<E>) super.clone(); 265 vector.elementData = elementData.clone(); 266 return vector; 267 } catch (CloneNotSupportedException e) { 268 return null; 269 } 270 } 271 272 /** 273 * Searches this vector for the specified object. 274 * 275 * @param object 276 * the object to look for in this vector. 277 * @return {@code true} if object is an element of this vector, 278 * {@code false} otherwise. 279 * @see #indexOf(Object) 280 * @see #indexOf(Object, int) 281 * @see java.lang.Object#equals 282 */ 283 @Override contains(Object object)284 public boolean contains(Object object) { 285 return indexOf(object, 0) != -1; 286 } 287 288 /** 289 * Searches this vector for all objects in the specified collection. 290 * 291 * @param collection 292 * the collection of objects. 293 * @return {@code true} if all objects in the specified collection are 294 * elements of this vector, {@code false} otherwise. 295 */ 296 @Override containsAll(Collection<?> collection)297 public synchronized boolean containsAll(Collection<?> collection) { 298 return super.containsAll(collection); 299 } 300 301 /** 302 * Attempts to copy elements contained by this {@code Vector} into the 303 * corresponding elements of the supplied {@code Object} array. 304 * 305 * @param elements 306 * the {@code Object} array into which the elements of this 307 * vector are copied. 308 * @throws IndexOutOfBoundsException 309 * if {@code elements} is not big enough. 310 * @see #clone 311 */ copyInto(Object[] elements)312 public synchronized void copyInto(Object[] elements) { 313 System.arraycopy(elementData, 0, elements, 0, elementCount); 314 } 315 316 /** 317 * Returns the element at the specified location in this vector. 318 * 319 * @param location 320 * the index of the element to return in this vector. 321 * @return the element at the specified location. 322 * @throws ArrayIndexOutOfBoundsException 323 * if {@code location < 0 || location >= size()}. 324 * @see #size 325 */ 326 @SuppressWarnings("unchecked") elementAt(int location)327 public synchronized E elementAt(int location) { 328 if (location < elementCount) { 329 return (E) elementData[location]; 330 } 331 throw new ArrayIndexOutOfBoundsException(location); 332 } 333 334 /** 335 * Returns an enumeration on the elements of this vector. The results of the 336 * enumeration may be affected if the contents of this vector is modified. 337 * 338 * @return an enumeration of the elements of this vector. 339 * @see #elementAt 340 * @see Enumeration 341 */ elements()342 public Enumeration<E> elements() { 343 return new Enumeration<E>() { 344 int pos = 0; 345 346 public boolean hasMoreElements() { 347 return pos < elementCount; 348 } 349 350 @SuppressWarnings("unchecked") 351 public E nextElement() { 352 synchronized (Vector.this) { 353 if (pos < elementCount) { 354 return (E) elementData[pos++]; 355 } 356 } 357 throw new NoSuchElementException(); 358 } 359 }; 360 } 361 362 /** 363 * Ensures that this vector can hold the specified number of elements 364 * without growing. 365 * 366 * @param minimumCapacity 367 * the minimum number of elements that this vector will hold 368 * before growing. 369 * @see #capacity 370 */ ensureCapacity(int minimumCapacity)371 public synchronized void ensureCapacity(int minimumCapacity) { 372 if (elementData.length < minimumCapacity) { 373 int next = (capacityIncrement <= 0 ? elementData.length 374 : capacityIncrement) 375 + elementData.length; 376 grow(minimumCapacity > next ? minimumCapacity : next); 377 } 378 } 379 380 /** 381 * Compares the specified object to this vector and returns if they are 382 * equal. The object must be a List which contains the same objects in the 383 * same order. 384 * 385 * @param object 386 * the object to compare with this object 387 * @return {@code true} if the specified object is equal to this vector, 388 * {@code false} otherwise. 389 * @see #hashCode 390 */ 391 @Override equals(Object object)392 public synchronized boolean equals(Object object) { 393 if (this == object) { 394 return true; 395 } 396 if (object instanceof List) { 397 List<?> list = (List<?>) object; 398 if (list.size() != elementCount) { 399 return false; 400 } 401 402 int index = 0; 403 Iterator<?> it = list.iterator(); 404 while (it.hasNext()) { 405 Object e1 = elementData[index++], e2 = it.next(); 406 if (!(e1 == null ? e2 == null : e1.equals(e2))) { 407 return false; 408 } 409 } 410 return true; 411 } 412 return false; 413 } 414 415 /** 416 * Returns the first element in this vector. 417 * 418 * @return the element at the first position. 419 * @throws NoSuchElementException 420 * if this vector is empty. 421 * @see #elementAt 422 * @see #lastElement 423 * @see #size 424 */ 425 @SuppressWarnings("unchecked") firstElement()426 public synchronized E firstElement() { 427 if (elementCount > 0) { 428 return (E) elementData[0]; 429 } 430 throw new NoSuchElementException(); 431 } 432 433 /** 434 * Returns the element at the specified location in this vector. 435 * 436 * @param location 437 * the index of the element to return in this vector. 438 * @return the element at the specified location. 439 * @throws ArrayIndexOutOfBoundsException 440 * if {@code location < 0 || location >= size()}. 441 * @see #size 442 */ 443 @Override get(int location)444 public E get(int location) { 445 return elementAt(location); 446 } 447 grow(int newCapacity)448 private void grow(int newCapacity) { 449 E[] newData = newElementArray(newCapacity); 450 // Assumes elementCount is <= newCapacity 451 assert elementCount <= newCapacity; 452 System.arraycopy(elementData, 0, newData, 0, elementCount); 453 elementData = newData; 454 } 455 456 /** 457 * JIT optimization 458 */ growByOne()459 private void growByOne() { 460 int adding = 0; 461 if (capacityIncrement <= 0) { 462 if ((adding = elementData.length) == 0) { 463 adding = 1; 464 } 465 } else { 466 adding = capacityIncrement; 467 } 468 469 E[] newData = newElementArray(elementData.length + adding); 470 System.arraycopy(elementData, 0, newData, 0, elementCount); 471 elementData = newData; 472 } 473 growBy(int required)474 private void growBy(int required) { 475 int adding = 0; 476 if (capacityIncrement <= 0) { 477 if ((adding = elementData.length) == 0) { 478 adding = required; 479 } 480 while (adding < required) { 481 adding += adding; 482 } 483 } else { 484 adding = (required / capacityIncrement) * capacityIncrement; 485 if (adding < required) { 486 adding += capacityIncrement; 487 } 488 } 489 E[] newData = newElementArray(elementData.length + adding); 490 System.arraycopy(elementData, 0, newData, 0, elementCount); 491 elementData = newData; 492 } 493 494 /** 495 * Returns an integer hash code for the receiver. Objects which are equal 496 * return the same value for this method. 497 * 498 * @return the receiver's hash. 499 * @see #equals 500 */ 501 @Override hashCode()502 public synchronized int hashCode() { 503 int result = 1; 504 for (int i = 0; i < elementCount; i++) { 505 result = (31 * result) 506 + (elementData[i] == null ? 0 : elementData[i].hashCode()); 507 } 508 return result; 509 } 510 511 /** 512 * Searches in this vector for the index of the specified object. The search 513 * for the object starts at the beginning and moves towards the end of this 514 * vector. 515 * 516 * @param object 517 * the object to find in this vector. 518 * @return the index in this vector of the specified element, -1 if the 519 * element isn't found. 520 * @see #contains 521 * @see #lastIndexOf(Object) 522 * @see #lastIndexOf(Object, int) 523 */ 524 @Override indexOf(Object object)525 public int indexOf(Object object) { 526 return indexOf(object, 0); 527 } 528 529 /** 530 * Searches in this vector for the index of the specified object. The search 531 * for the object starts at the specified location and moves towards the end 532 * of this vector. 533 * 534 * @param object 535 * the object to find in this vector. 536 * @param location 537 * the index at which to start searching. 538 * @return the index in this vector of the specified element, -1 if the 539 * element isn't found. 540 * @throws ArrayIndexOutOfBoundsException 541 * if {@code location < 0}. 542 * @see #contains 543 * @see #lastIndexOf(Object) 544 * @see #lastIndexOf(Object, int) 545 */ indexOf(Object object, int location)546 public synchronized int indexOf(Object object, int location) { 547 if (object != null) { 548 for (int i = location; i < elementCount; i++) { 549 if (object.equals(elementData[i])) { 550 return i; 551 } 552 } 553 } else { 554 for (int i = location; i < elementCount; i++) { 555 if (elementData[i] == null) { 556 return i; 557 } 558 } 559 } 560 return -1; 561 } 562 563 /** 564 * Inserts the specified object into this vector at the specified location. 565 * This object is inserted before any previous element at the specified 566 * location. All elements with an index equal or greater than 567 * {@code location} have their index increased by 1. If the location is 568 * equal to the size of this vector, the object is added at the end. 569 * 570 * @param object 571 * the object to insert in this vector. 572 * @param location 573 * the index at which to insert the element. 574 * @throws ArrayIndexOutOfBoundsException 575 * if {@code location < 0 || location > size()}. 576 * @see #addElement 577 * @see #size 578 */ insertElementAt(E object, int location)579 public synchronized void insertElementAt(E object, int location) { 580 if (0 <= location && location <= elementCount) { 581 if (elementCount == elementData.length) { 582 growByOne(); 583 } 584 int count = elementCount - location; 585 if (count > 0) { 586 System.arraycopy(elementData, location, elementData, 587 location + 1, count); 588 } 589 elementData[location] = object; 590 elementCount++; 591 modCount++; 592 } else { 593 throw new ArrayIndexOutOfBoundsException(location); 594 } 595 } 596 597 /** 598 * Returns if this vector has no elements, a size of zero. 599 * 600 * @return {@code true} if this vector has no elements, {@code false} 601 * otherwise. 602 * @see #size 603 */ 604 @Override isEmpty()605 public synchronized boolean isEmpty() { 606 return elementCount == 0; 607 } 608 609 /** 610 * Returns the last element in this vector. 611 * 612 * @return the element at the last position. 613 * @throws NoSuchElementException 614 * if this vector is empty. 615 * @see #elementAt 616 * @see #firstElement 617 * @see #size 618 */ 619 @SuppressWarnings("unchecked") lastElement()620 public synchronized E lastElement() { 621 try { 622 return (E) elementData[elementCount - 1]; 623 } catch (IndexOutOfBoundsException e) { 624 throw new NoSuchElementException(); 625 } 626 } 627 628 /** 629 * Searches in this vector for the index of the specified object. The search 630 * for the object starts at the end and moves towards the start of this 631 * vector. 632 * 633 * @param object 634 * the object to find in this vector. 635 * @return the index in this vector of the specified element, -1 if the 636 * element isn't found. 637 * @see #contains 638 * @see #indexOf(Object) 639 * @see #indexOf(Object, int) 640 */ 641 @Override lastIndexOf(Object object)642 public synchronized int lastIndexOf(Object object) { 643 return lastIndexOf(object, elementCount - 1); 644 } 645 646 /** 647 * Searches in this vector for the index of the specified object. The search 648 * for the object starts at the specified location and moves towards the 649 * start of this vector. 650 * 651 * @param object 652 * the object to find in this vector. 653 * @param location 654 * the index at which to start searching. 655 * @return the index in this vector of the specified element, -1 if the 656 * element isn't found. 657 * @throws ArrayIndexOutOfBoundsException 658 * if {@code location >= size()}. 659 * @see #contains 660 * @see #indexOf(Object) 661 * @see #indexOf(Object, int) 662 */ lastIndexOf(Object object, int location)663 public synchronized int lastIndexOf(Object object, int location) { 664 if (location < elementCount) { 665 if (object != null) { 666 for (int i = location; i >= 0; i--) { 667 if (object.equals(elementData[i])) { 668 return i; 669 } 670 } 671 } else { 672 for (int i = location; i >= 0; i--) { 673 if (elementData[i] == null) { 674 return i; 675 } 676 } 677 } 678 return -1; 679 } 680 throw new ArrayIndexOutOfBoundsException(location); 681 } 682 683 /** 684 * Removes the object at the specified location from this vector. All 685 * elements with an index bigger than {@code location} have their index 686 * decreased by 1. 687 * 688 * @param location 689 * the index of the object to remove. 690 * @return the removed object. 691 * @throws IndexOutOfBoundsException 692 * if {@code location < 0 || location >= size()}. 693 */ 694 @SuppressWarnings("unchecked") 695 @Override remove(int location)696 public synchronized E remove(int location) { 697 if (location < elementCount) { 698 E result = (E) elementData[location]; 699 elementCount--; 700 int size = elementCount - location; 701 if (size > 0) { 702 System.arraycopy(elementData, location + 1, elementData, 703 location, size); 704 } 705 elementData[elementCount] = null; 706 modCount++; 707 return result; 708 } 709 throw new ArrayIndexOutOfBoundsException(location); 710 } 711 712 /** 713 * Removes the first occurrence, starting at the beginning and moving 714 * towards the end, of the specified object from this vector. All elements 715 * with an index bigger than the element that gets removed have their index 716 * decreased by 1. 717 * 718 * @param object 719 * the object to remove from this vector. 720 * @return {@code true} if the specified object was found, {@code false} 721 * otherwise. 722 * @see #removeAllElements 723 * @see #removeElementAt 724 * @see #size 725 */ 726 @Override remove(Object object)727 public boolean remove(Object object) { 728 return removeElement(object); 729 } 730 731 /** 732 * Removes all occurrences in this vector of each object in the specified 733 * Collection. 734 * 735 * @param collection 736 * the collection of objects to remove. 737 * @return {@code true} if this vector is modified, {@code false} otherwise. 738 * @see #remove(Object) 739 * @see #contains(Object) 740 */ 741 @Override removeAll(Collection<?> collection)742 public synchronized boolean removeAll(Collection<?> collection) { 743 return super.removeAll(collection); 744 } 745 746 /** 747 * Removes all elements from this vector, leaving the size zero and the 748 * capacity unchanged. 749 * 750 * @see #isEmpty 751 * @see #size 752 */ removeAllElements()753 public synchronized void removeAllElements() { 754 for (int i = 0; i < elementCount; i++) { 755 elementData[i] = null; 756 } 757 modCount++; 758 elementCount = 0; 759 } 760 761 /** 762 * Removes the first occurrence, starting at the beginning and moving 763 * towards the end, of the specified object from this vector. All elements 764 * with an index bigger than the element that gets removed have their index 765 * decreased by 1. 766 * 767 * @param object 768 * the object to remove from this vector. 769 * @return {@code true} if the specified object was found, {@code false} 770 * otherwise. 771 * @see #removeAllElements 772 * @see #removeElementAt 773 * @see #size 774 */ removeElement(Object object)775 public synchronized boolean removeElement(Object object) { 776 int index; 777 if ((index = indexOf(object, 0)) == -1) { 778 return false; 779 } 780 removeElementAt(index); 781 return true; 782 } 783 784 /** 785 * Removes the element found at index position {@code location} from 786 * this {@code Vector}. All elements with an index bigger than 787 * {@code location} have their index decreased by 1. 788 * 789 * @param location 790 * the index of the element to remove. 791 * @throws ArrayIndexOutOfBoundsException 792 * if {@code location < 0 || location >= size()}. 793 * @see #removeElement 794 * @see #removeAllElements 795 * @see #size 796 */ removeElementAt(int location)797 public synchronized void removeElementAt(int location) { 798 if (0 <= location && location < elementCount) { 799 elementCount--; 800 int size = elementCount - location; 801 if (size > 0) { 802 System.arraycopy(elementData, location + 1, elementData, 803 location, size); 804 } 805 elementData[elementCount] = null; 806 modCount++; 807 } else { 808 throw new ArrayIndexOutOfBoundsException(location); 809 } 810 } 811 812 /** 813 * Removes the objects in the specified range from the start to the, but not 814 * including, end index. All elements with an index bigger than or equal to 815 * {@code end} have their index decreased by {@code end - start}. 816 * 817 * @param start 818 * the index at which to start removing. 819 * @param end 820 * the index one past the end of the range to remove. 821 * @throws IndexOutOfBoundsException 822 * if {@code start < 0, start > end} or 823 * {@code end > size()}. 824 */ 825 @Override removeRange(int start, int end)826 protected void removeRange(int start, int end) { 827 if (start >= 0 && start <= end && end <= elementCount) { 828 if (start == end) { 829 return; 830 } 831 if (end != elementCount) { 832 System.arraycopy(elementData, end, elementData, start, 833 elementCount - end); 834 int newCount = elementCount - (end - start); 835 Arrays.fill(elementData, newCount, elementCount, null); 836 elementCount = newCount; 837 } else { 838 Arrays.fill(elementData, start, elementCount, null); 839 elementCount = start; 840 } 841 modCount++; 842 } else { 843 throw new IndexOutOfBoundsException(); 844 } 845 } 846 847 /** 848 * Removes all objects from this vector that are not contained in the 849 * specified collection. 850 * 851 * @param collection 852 * the collection of objects to retain. 853 * @return {@code true} if this vector is modified, {@code false} otherwise. 854 * @see #remove(Object) 855 */ 856 @Override retainAll(Collection<?> collection)857 public synchronized boolean retainAll(Collection<?> collection) { 858 return super.retainAll(collection); 859 } 860 861 /** 862 * Replaces the element at the specified location in this vector with the 863 * specified object. 864 * 865 * @param location 866 * the index at which to put the specified object. 867 * @param object 868 * the object to add to this vector. 869 * @return the previous element at the location. 870 * @throws ArrayIndexOutOfBoundsException 871 * if {@code location < 0 || location >= size()}. 872 * @see #size 873 */ 874 @SuppressWarnings("unchecked") 875 @Override set(int location, E object)876 public synchronized E set(int location, E object) { 877 if (location < elementCount) { 878 E result = (E) elementData[location]; 879 elementData[location] = object; 880 return result; 881 } 882 throw new ArrayIndexOutOfBoundsException(location); 883 } 884 885 /** 886 * Replaces the element at the specified location in this vector with the 887 * specified object. 888 * 889 * @param object 890 * the object to add to this vector. 891 * @param location 892 * the index at which to put the specified object. 893 * @throws ArrayIndexOutOfBoundsException 894 * if {@code location < 0 || location >= size()}. 895 * @see #size 896 */ setElementAt(E object, int location)897 public synchronized void setElementAt(E object, int location) { 898 if (location < elementCount) { 899 elementData[location] = object; 900 } else { 901 throw new ArrayIndexOutOfBoundsException(location); 902 } 903 } 904 905 /** 906 * Sets the size of this vector to the specified size. If there are more 907 * than length elements in this vector, the elements at end are lost. If 908 * there are less than length elements in the vector, the additional 909 * elements contain null. 910 * 911 * @param length 912 * the new size of this vector. 913 * @see #size 914 */ setSize(int length)915 public synchronized void setSize(int length) { 916 if (length == elementCount) { 917 return; 918 } 919 ensureCapacity(length); 920 if (elementCount > length) { 921 Arrays.fill(elementData, length, elementCount, null); 922 } 923 elementCount = length; 924 modCount++; 925 } 926 927 /** 928 * Returns the number of elements in this vector. 929 * 930 * @return the number of elements in this vector. 931 * @see #elementCount 932 * @see #lastElement 933 */ 934 @Override size()935 public synchronized int size() { 936 return elementCount; 937 } 938 939 /** 940 * Returns a List of the specified portion of this vector from the start 941 * index to one less than the end index. The returned List is backed by this 942 * vector so changes to one are reflected by the other. 943 * 944 * @param start 945 * the index at which to start the sublist. 946 * @param end 947 * the index one past the end of the sublist. 948 * @return a List of a portion of this vector. 949 * @throws IndexOutOfBoundsException 950 * if {@code start < 0} or {@code end > size()}. 951 * @throws IllegalArgumentException 952 * if {@code start > end}. 953 */ 954 @Override subList(int start, int end)955 public synchronized List<E> subList(int start, int end) { 956 return new Collections.SynchronizedRandomAccessList<E>(super.subList( 957 start, end), this); 958 } 959 960 /** 961 * Returns a new array containing all elements contained in this vector. 962 * 963 * @return an array of the elements from this vector. 964 */ 965 @Override toArray()966 public synchronized Object[] toArray() { 967 Object[] result = new Object[elementCount]; 968 System.arraycopy(elementData, 0, result, 0, elementCount); 969 return result; 970 } 971 972 /** 973 * Returns an array containing all elements contained in this vector. If the 974 * specified array is large enough to hold the elements, the specified array 975 * is used, otherwise an array of the same type is created. If the specified 976 * array is used and is larger than this vector, the array element following 977 * the collection elements is set to null. 978 * 979 * @param contents 980 * the array to fill. 981 * @return an array of the elements from this vector. 982 * @throws ArrayStoreException 983 * if the type of an element in this vector cannot be 984 * stored in the type of the specified array. 985 */ 986 @Override 987 @SuppressWarnings("unchecked") toArray(T[] contents)988 public synchronized <T> T[] toArray(T[] contents) { 989 if (elementCount > contents.length) { 990 Class<?> ct = contents.getClass().getComponentType(); 991 contents = (T[]) Array.newInstance(ct, elementCount); 992 } 993 System.arraycopy(elementData, 0, contents, 0, elementCount); 994 if (elementCount < contents.length) { 995 contents[elementCount] = null; 996 } 997 return contents; 998 } 999 1000 /** 1001 * Returns the string representation of this vector. 1002 * 1003 * @return the string representation of this vector. 1004 * @see #elements 1005 */ 1006 @Override toString()1007 public synchronized String toString() { 1008 if (elementCount == 0) { 1009 return "[]"; //$NON-NLS-1$ 1010 } 1011 int length = elementCount - 1; 1012 StringBuilder buffer = new StringBuilder(elementCount * 16); 1013 buffer.append('['); 1014 for (int i = 0; i < length; i++) { 1015 if (elementData[i] == this) { 1016 buffer.append("(this Collection)"); //$NON-NLS-1$ 1017 } else { 1018 buffer.append(elementData[i]); 1019 } 1020 buffer.append(", "); //$NON-NLS-1$ 1021 } 1022 if (elementData[length] == this) { 1023 buffer.append("(this Collection)"); //$NON-NLS-1$ 1024 } else { 1025 buffer.append(elementData[length]); 1026 } 1027 buffer.append(']'); 1028 return buffer.toString(); 1029 } 1030 1031 /** 1032 * Sets the capacity of this vector to be the same as the size. 1033 * 1034 * @see #capacity 1035 * @see #ensureCapacity 1036 * @see #size 1037 */ trimToSize()1038 public synchronized void trimToSize() { 1039 if (elementData.length != elementCount) { 1040 grow(elementCount); 1041 } 1042 } 1043 writeObject(ObjectOutputStream stream)1044 private synchronized void writeObject(ObjectOutputStream stream) 1045 throws IOException { 1046 stream.defaultWriteObject(); 1047 } 1048 } 1049