135 |
|
elementData = Arrays.copyOf(elementData, size, Object[].class); |
136 |
|
} |
137 |
|
|
138 |
+ |
private void initFromConcurrentlyMutating(Collection<? extends E> c) { |
139 |
+ |
elementData = c.toArray(); |
140 |
+ |
size = elementData.length; |
141 |
+ |
// c.toArray might (incorrectly) not return Object[] (see 6260652) |
142 |
+ |
if (elementData.getClass() != Object[].class) |
143 |
+ |
elementData = Arrays.copyOf(elementData, size, Object[].class); |
144 |
+ |
} |
145 |
+ |
|
146 |
+ |
private final static Object UNALLOCATED = new Object(); |
147 |
+ |
|
148 |
|
/** |
149 |
|
* Trims the capacity of this <tt>ArrayList</tt> instance to be the |
150 |
|
* list's current size. An application can use this operation to minimize |
177 |
|
* @param minCapacity the desired minimum capacity |
178 |
|
*/ |
179 |
|
private void growArray(int minCapacity) { |
180 |
< |
if (minCapacity < 0) // overflow |
181 |
< |
throw new OutOfMemoryError(); |
180 |
> |
if (minCapacity < 0) // overflow |
181 |
> |
throw new OutOfMemoryError(); |
182 |
|
int oldCapacity = elementData.length; |
183 |
|
// Double size if small; else grow by 50% |
184 |
< |
int newCapacity = ((oldCapacity < 64)? |
185 |
< |
((oldCapacity + 1) * 2): |
184 |
> |
int newCapacity = ((oldCapacity < 64) ? |
185 |
> |
((oldCapacity + 1) * 2) : |
186 |
|
((oldCapacity / 2) * 3)); |
187 |
|
if (newCapacity < 0) // overflow |
188 |
|
newCapacity = Integer.MAX_VALUE; |
335 |
|
// Positional Access Operations |
336 |
|
|
337 |
|
/** |
338 |
< |
* Returns error message string for IndexOutOfBoundsExceptions |
338 |
> |
* Throws an appropriate exception for indexing errors. |
339 |
|
*/ |
340 |
< |
private String ioobe(int index) { |
341 |
< |
return "Index: " + index + ", Size: " + size; |
340 |
> |
private static void indexOutOfBounds(int i, int s) { |
341 |
> |
throw new IndexOutOfBoundsException("Index: " + i + ", Size: " + s); |
342 |
|
} |
343 |
|
|
344 |
|
/** |
350 |
|
*/ |
351 |
|
public E get(int index) { |
352 |
|
if (index >= size) |
353 |
< |
throw new IndexOutOfBoundsException(ioobe(index)); |
354 |
< |
return (E)elementData[index]; |
353 |
> |
indexOutOfBounds(index, size); |
354 |
> |
return (E) elementData[index]; |
355 |
|
} |
356 |
|
|
357 |
|
/** |
365 |
|
*/ |
366 |
|
public E set(int index, E element) { |
367 |
|
if (index >= size) |
368 |
< |
throw new IndexOutOfBoundsException(ioobe(index)); |
359 |
< |
|
368 |
> |
indexOutOfBounds(index, size); |
369 |
|
E oldValue = (E) elementData[index]; |
370 |
|
elementData[index] = element; |
371 |
|
return oldValue; |
383 |
|
if (s >= elementData.length) |
384 |
|
growArray(s + 1); |
385 |
|
elementData[s] = e; |
386 |
< |
size = s + 1; |
387 |
< |
return true; |
386 |
> |
size = s + 1; |
387 |
> |
return true; |
388 |
|
} |
389 |
|
|
390 |
|
/** |
399 |
|
public void add(int index, E element) { |
400 |
|
int s = size; |
401 |
|
if (index > s || index < 0) |
402 |
< |
throw new IndexOutOfBoundsException(ioobe(index)); |
402 |
> |
indexOutOfBounds(index, s); |
403 |
|
modCount++; |
404 |
|
if (s >= elementData.length) |
405 |
|
growArray(s + 1); |
406 |
|
System.arraycopy(elementData, index, |
407 |
< |
elementData, index + 1, s - index); |
407 |
> |
elementData, index + 1, s - index); |
408 |
|
elementData[index] = element; |
409 |
|
size = s + 1; |
410 |
|
} |
421 |
|
public E remove(int index) { |
422 |
|
int s = size - 1; |
423 |
|
if (index > s) |
424 |
< |
throw new IndexOutOfBoundsException(ioobe(index)); |
424 |
> |
indexOutOfBounds(index, size); |
425 |
|
modCount++; |
426 |
< |
E oldValue = (E)elementData[index]; |
426 |
> |
E oldValue = (E) elementData[index]; |
427 |
|
int numMoved = s - index; |
428 |
|
if (numMoved > 0) |
429 |
|
System.arraycopy(elementData, index + 1, |
430 |
< |
elementData, index, numMoved); |
430 |
> |
elementData, index, numMoved); |
431 |
|
elementData[s] = null; |
432 |
< |
size = s; |
432 |
> |
size = s; |
433 |
|
return oldValue; |
434 |
|
} |
435 |
|
|
529 |
|
*/ |
530 |
|
public boolean addAll(int index, Collection<? extends E> c) { |
531 |
|
if (index > size || index < 0) |
532 |
< |
throw new IndexOutOfBoundsException(ioobe(index)); |
532 |
> |
indexOutOfBounds(index, size); |
533 |
|
|
534 |
|
Object[] a = c.toArray(); |
535 |
|
int numNew = a.length; |
614 |
|
for (int i=0; i<size; i++) |
615 |
|
a[i] = s.readObject(); |
616 |
|
} |
608 |
– |
|
609 |
– |
|
610 |
– |
/** |
611 |
– |
* Returns a list-iterator of the elements in this list (in proper |
612 |
– |
* sequence), starting at the specified position in the list. |
613 |
– |
* Obeys the general contract of <tt>List.listIterator(int)</tt>.<p> |
614 |
– |
* |
615 |
– |
* The list-iterator is <i>fail-fast</i>: if the list is structurally |
616 |
– |
* modified at any time after the Iterator is created, in any way except |
617 |
– |
* through the list-iterator's own <tt>remove</tt> or <tt>add</tt> |
618 |
– |
* methods, the list-iterator will throw a |
619 |
– |
* <tt>ConcurrentModificationException</tt>. Thus, in the face of |
620 |
– |
* concurrent modification, the iterator fails quickly and cleanly, rather |
621 |
– |
* than risking arbitrary, non-deterministic behavior at an undetermined |
622 |
– |
* time in the future. |
623 |
– |
* |
624 |
– |
* @param index index of the first element to be returned from the |
625 |
– |
* list-iterator (by a call to <tt>next</tt>) |
626 |
– |
* @return a ListIterator of the elements in this list (in proper |
627 |
– |
* sequence), starting at the specified position in the list |
628 |
– |
* @throws IndexOutOfBoundsException {@inheritDoc} |
629 |
– |
* @see List#listIterator(int) |
630 |
– |
*/ |
631 |
– |
public ListIterator<E> listIterator(int index) { |
632 |
– |
if (index < 0 || index > size) |
633 |
– |
throw new IndexOutOfBoundsException(ioobe(index)); |
634 |
– |
return new ArrayListIterator(index); |
635 |
– |
} |
636 |
– |
|
637 |
– |
/** |
638 |
– |
* {@inheritDoc} |
639 |
– |
*/ |
640 |
– |
public ListIterator<E> listIterator() { |
641 |
– |
return new ArrayListIterator(0); |
642 |
– |
} |
643 |
– |
|
644 |
– |
/** |
645 |
– |
* Returns an iterator over the elements in this list in proper sequence. |
646 |
– |
* |
647 |
– |
* @return an iterator over the elements in this list in proper sequence |
648 |
– |
*/ |
649 |
– |
public Iterator<E> iterator() { |
650 |
– |
return new ArrayListIterator(0); |
651 |
– |
} |
652 |
– |
|
653 |
– |
/** |
654 |
– |
* A streamlined version of AbstractList.ListItr |
655 |
– |
*/ |
656 |
– |
final class ArrayListIterator implements ListIterator<E> { |
657 |
– |
int cursor; // index of next element to return; |
658 |
– |
int lastRet; // index of last element, or -1 if no such |
659 |
– |
int expectedModCount; // to check for CME |
660 |
– |
|
661 |
– |
ArrayListIterator(int index) { |
662 |
– |
cursor = index; |
663 |
– |
lastRet = -1; |
664 |
– |
expectedModCount = modCount; |
665 |
– |
} |
666 |
– |
|
667 |
– |
public boolean hasNext() { |
668 |
– |
return cursor != size; |
669 |
– |
} |
670 |
– |
|
671 |
– |
public boolean hasPrevious() { |
672 |
– |
return cursor != 0; |
673 |
– |
} |
674 |
– |
|
675 |
– |
public int nextIndex() { |
676 |
– |
return cursor; |
677 |
– |
} |
678 |
– |
|
679 |
– |
public int previousIndex() { |
680 |
– |
return cursor - 1; |
681 |
– |
} |
682 |
– |
|
683 |
– |
public E next() { |
684 |
– |
try { |
685 |
– |
int i = cursor; |
686 |
– |
E next = get(i); |
687 |
– |
lastRet = i; |
688 |
– |
cursor = i + 1; |
689 |
– |
return next; |
690 |
– |
} catch (IndexOutOfBoundsException ex) { |
691 |
– |
throw new NoSuchElementException(); |
692 |
– |
} finally { |
693 |
– |
if (expectedModCount != modCount) |
694 |
– |
throw new ConcurrentModificationException(); |
695 |
– |
} |
696 |
– |
} |
697 |
– |
|
698 |
– |
public E previous() { |
699 |
– |
try { |
700 |
– |
int i = cursor - 1; |
701 |
– |
E prev = get(i); |
702 |
– |
lastRet = i; |
703 |
– |
cursor = i; |
704 |
– |
return prev; |
705 |
– |
} catch (IndexOutOfBoundsException ex) { |
706 |
– |
throw new NoSuchElementException(); |
707 |
– |
} finally { |
708 |
– |
if (expectedModCount != modCount) |
709 |
– |
throw new ConcurrentModificationException(); |
710 |
– |
} |
711 |
– |
} |
712 |
– |
|
713 |
– |
public void remove() { |
714 |
– |
if (lastRet < 0) |
715 |
– |
throw new IllegalStateException(); |
716 |
– |
if (expectedModCount != modCount) |
717 |
– |
throw new ConcurrentModificationException(); |
718 |
– |
ArrayList.this.remove(lastRet); |
719 |
– |
if (lastRet < cursor) |
720 |
– |
cursor--; |
721 |
– |
lastRet = -1; |
722 |
– |
expectedModCount = modCount; |
723 |
– |
} |
724 |
– |
|
725 |
– |
public void set(E e) { |
726 |
– |
if (lastRet < 0) |
727 |
– |
throw new IllegalStateException(); |
728 |
– |
if (expectedModCount != modCount) |
729 |
– |
throw new ConcurrentModificationException(); |
730 |
– |
ArrayList.this.set(lastRet, e); |
731 |
– |
expectedModCount = modCount; |
732 |
– |
} |
733 |
– |
|
734 |
– |
public void add(E e) { |
735 |
– |
if (expectedModCount != modCount) |
736 |
– |
throw new ConcurrentModificationException(); |
737 |
– |
try { |
738 |
– |
ArrayList.this.add(cursor++, e); |
739 |
– |
lastRet = -1; |
740 |
– |
expectedModCount = modCount; |
741 |
– |
} catch (IndexOutOfBoundsException ex) { |
742 |
– |
throw new ConcurrentModificationException(); |
743 |
– |
} |
744 |
– |
} |
745 |
– |
} |
617 |
|
} |