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