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