ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java
(Generate patch)

Comparing jsr166/src/main/java/util/concurrent/CopyOnWriteArrayList.java (file contents):
Revision 1.66 by jsr166, Wed Aug 8 15:58:02 2007 UTC vs.
Revision 1.67 by jsr166, Sun May 18 23:47:56 2008 UTC

# Line 97 | Line 97 | public class CopyOnWriteArrayList<E>
97       * @throws NullPointerException if the specified collection is null
98       */
99      public CopyOnWriteArrayList(Collection<? extends E> c) {
100 <        Object[] elements = c.toArray();
101 <        // c.toArray might (incorrectly) not return Object[] (see 6260652)
102 <        if (elements.getClass() != Object[].class)
103 <            elements = Arrays.copyOf(elements, elements.length, Object[].class);
104 <        setArray(elements);
100 >        Object[] elements = c.toArray();
101 >        // c.toArray might (incorrectly) not return Object[] (see 6260652)
102 >        if (elements.getClass() != Object[].class)
103 >            elements = Arrays.copyOf(elements, elements.length, Object[].class);
104 >        setArray(elements);
105      }
106  
107      /**
# Line 112 | Line 112 | public class CopyOnWriteArrayList<E>
112       * @throws NullPointerException if the specified array is null
113       */
114      public CopyOnWriteArrayList(E[] toCopyIn) {
115 <        setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
115 >        setArray(Arrays.copyOf(toCopyIn, toCopyIn.length, Object[].class));
116      }
117  
118      /**
# Line 222 | Line 222 | public class CopyOnWriteArrayList<E>
222       */
223      public int indexOf(E e, int index) {
224          Object[] elements = getArray();
225 <        return indexOf(e, elements, index, elements.length);
225 >        return indexOf(e, elements, index, elements.length);
226      }
227  
228      /**
# Line 251 | Line 251 | public class CopyOnWriteArrayList<E>
251       */
252      public int lastIndexOf(E e, int index) {
253          Object[] elements = getArray();
254 <        return lastIndexOf(e, elements, index);
254 >        return lastIndexOf(e, elements, index);
255      }
256  
257      /**
# Line 286 | Line 286 | public class CopyOnWriteArrayList<E>
286       */
287      public Object[] toArray() {
288          Object[] elements = getArray();
289 <        return Arrays.copyOf(elements, elements.length);
289 >        return Arrays.copyOf(elements, elements.length);
290      }
291  
292      /**
# Line 333 | Line 333 | public class CopyOnWriteArrayList<E>
333          Object[] elements = getArray();
334          int len = elements.length;
335          if (a.length < len)
336 <            return (T[]) Arrays.copyOf(elements, len, a.getClass());
337 <        else {
338 <            System.arraycopy(elements, 0, a, 0, len);
339 <            if (a.length > len)
340 <                a[len] = null;
341 <            return a;
342 <        }
336 >            return (T[]) Arrays.copyOf(elements, len, a.getClass());
337 >        else {
338 >            System.arraycopy(elements, 0, a, 0, len);
339 >            if (a.length > len)
340 >                a[len] = null;
341 >            return a;
342 >        }
343      }
344  
345      // Positional Access Operations
346  
347      @SuppressWarnings("unchecked")
348      private E get(Object[] a, int index) {
349 <        return (E) a[index];
349 >        return (E) a[index];
350      }
351  
352      /**
# Line 365 | Line 365 | public class CopyOnWriteArrayList<E>
365       * @throws IndexOutOfBoundsException {@inheritDoc}
366       */
367      public E set(int index, E element) {
368 <        final ReentrantLock lock = this.lock;
369 <        lock.lock();
370 <        try {
371 <            Object[] elements = getArray();
372 <            E oldValue = get(elements, index);
373 <
374 <            if (oldValue != element) {
375 <                int len = elements.length;
376 <                Object[] newElements = Arrays.copyOf(elements, len);
377 <                newElements[index] = element;
378 <                setArray(newElements);
379 <            } else {
380 <                // Not quite a no-op; ensures volatile write semantics
381 <                setArray(elements);
382 <            }
383 <            return oldValue;
384 <        } finally {
385 <            lock.unlock();
386 <        }
368 >        final ReentrantLock lock = this.lock;
369 >        lock.lock();
370 >        try {
371 >            Object[] elements = getArray();
372 >            E oldValue = get(elements, index);
373 >
374 >            if (oldValue != element) {
375 >                int len = elements.length;
376 >                Object[] newElements = Arrays.copyOf(elements, len);
377 >                newElements[index] = element;
378 >                setArray(newElements);
379 >            } else {
380 >                // Not quite a no-op; ensures volatile write semantics
381 >                setArray(elements);
382 >            }
383 >            return oldValue;
384 >        } finally {
385 >            lock.unlock();
386 >        }
387      }
388  
389      /**
# Line 393 | Line 393 | public class CopyOnWriteArrayList<E>
393       * @return <tt>true</tt> (as specified by {@link Collection#add})
394       */
395      public boolean add(E e) {
396 <        final ReentrantLock lock = this.lock;
397 <        lock.lock();
398 <        try {
399 <            Object[] elements = getArray();
400 <            int len = elements.length;
401 <            Object[] newElements = Arrays.copyOf(elements, len + 1);
402 <            newElements[len] = e;
403 <            setArray(newElements);
404 <            return true;
405 <        } finally {
406 <            lock.unlock();
407 <        }
396 >        final ReentrantLock lock = this.lock;
397 >        lock.lock();
398 >        try {
399 >            Object[] elements = getArray();
400 >            int len = elements.length;
401 >            Object[] newElements = Arrays.copyOf(elements, len + 1);
402 >            newElements[len] = e;
403 >            setArray(newElements);
404 >            return true;
405 >        } finally {
406 >            lock.unlock();
407 >        }
408      }
409  
410      /**
# Line 415 | Line 415 | public class CopyOnWriteArrayList<E>
415       * @throws IndexOutOfBoundsException {@inheritDoc}
416       */
417      public void add(int index, E element) {
418 <        final ReentrantLock lock = this.lock;
419 <        lock.lock();
420 <        try {
421 <            Object[] elements = getArray();
422 <            int len = elements.length;
423 <            if (index > len || index < 0)
424 <                throw new IndexOutOfBoundsException("Index: "+index+
425 <                                                    ", Size: "+len);
426 <            Object[] newElements;
427 <            int numMoved = len - index;
428 <            if (numMoved == 0)
429 <                newElements = Arrays.copyOf(elements, len + 1);
430 <            else {
431 <                newElements = new Object[len + 1];
432 <                System.arraycopy(elements, 0, newElements, 0, index);
433 <                System.arraycopy(elements, index, newElements, index + 1,
434 <                                 numMoved);
435 <            }
436 <            newElements[index] = element;
437 <            setArray(newElements);
438 <        } finally {
439 <            lock.unlock();
440 <        }
418 >        final ReentrantLock lock = this.lock;
419 >        lock.lock();
420 >        try {
421 >            Object[] elements = getArray();
422 >            int len = elements.length;
423 >            if (index > len || index < 0)
424 >                throw new IndexOutOfBoundsException("Index: "+index+
425 >                                                    ", Size: "+len);
426 >            Object[] newElements;
427 >            int numMoved = len - index;
428 >            if (numMoved == 0)
429 >                newElements = Arrays.copyOf(elements, len + 1);
430 >            else {
431 >                newElements = new Object[len + 1];
432 >                System.arraycopy(elements, 0, newElements, 0, index);
433 >                System.arraycopy(elements, index, newElements, index + 1,
434 >                                 numMoved);
435 >            }
436 >            newElements[index] = element;
437 >            setArray(newElements);
438 >        } finally {
439 >            lock.unlock();
440 >        }
441      }
442  
443      /**
# Line 448 | Line 448 | public class CopyOnWriteArrayList<E>
448       * @throws IndexOutOfBoundsException {@inheritDoc}
449       */
450      public E remove(int index) {
451 <        final ReentrantLock lock = this.lock;
452 <        lock.lock();
453 <        try {
454 <            Object[] elements = getArray();
455 <            int len = elements.length;
456 <            E oldValue = get(elements, index);
457 <            int numMoved = len - index - 1;
458 <            if (numMoved == 0)
459 <                setArray(Arrays.copyOf(elements, len - 1));
460 <            else {
461 <                Object[] newElements = new Object[len - 1];
462 <                System.arraycopy(elements, 0, newElements, 0, index);
463 <                System.arraycopy(elements, index + 1, newElements, index,
464 <                                 numMoved);
465 <                setArray(newElements);
466 <            }
467 <            return oldValue;
468 <        } finally {
469 <            lock.unlock();
470 <        }
451 >        final ReentrantLock lock = this.lock;
452 >        lock.lock();
453 >        try {
454 >            Object[] elements = getArray();
455 >            int len = elements.length;
456 >            E oldValue = get(elements, index);
457 >            int numMoved = len - index - 1;
458 >            if (numMoved == 0)
459 >                setArray(Arrays.copyOf(elements, len - 1));
460 >            else {
461 >                Object[] newElements = new Object[len - 1];
462 >                System.arraycopy(elements, 0, newElements, 0, index);
463 >                System.arraycopy(elements, index + 1, newElements, index,
464 >                                 numMoved);
465 >                setArray(newElements);
466 >            }
467 >            return oldValue;
468 >        } finally {
469 >            lock.unlock();
470 >        }
471      }
472  
473      /**
# Line 484 | Line 484 | public class CopyOnWriteArrayList<E>
484       * @return <tt>true</tt> if this list contained the specified element
485       */
486      public boolean remove(Object o) {
487 <        final ReentrantLock lock = this.lock;
488 <        lock.lock();
489 <        try {
490 <            Object[] elements = getArray();
491 <            int len = elements.length;
492 <            if (len != 0) {
493 <                // Copy while searching for element to remove
494 <                // This wins in the normal case of element being present
495 <                int newlen = len - 1;
496 <                Object[] newElements = new Object[newlen];
497 <
498 <                for (int i = 0; i < newlen; ++i) {
499 <                    if (eq(o, elements[i])) {
500 <                        // found one;  copy remaining and exit
501 <                        for (int k = i + 1; k < len; ++k)
502 <                            newElements[k-1] = elements[k];
503 <                        setArray(newElements);
504 <                        return true;
505 <                    } else
506 <                        newElements[i] = elements[i];
507 <                }
508 <
509 <                // special handling for last cell
510 <                if (eq(o, elements[newlen])) {
511 <                    setArray(newElements);
512 <                    return true;
513 <                }
514 <            }
515 <            return false;
516 <        } finally {
517 <            lock.unlock();
518 <        }
487 >        final ReentrantLock lock = this.lock;
488 >        lock.lock();
489 >        try {
490 >            Object[] elements = getArray();
491 >            int len = elements.length;
492 >            if (len != 0) {
493 >                // Copy while searching for element to remove
494 >                // This wins in the normal case of element being present
495 >                int newlen = len - 1;
496 >                Object[] newElements = new Object[newlen];
497 >
498 >                for (int i = 0; i < newlen; ++i) {
499 >                    if (eq(o, elements[i])) {
500 >                        // found one;  copy remaining and exit
501 >                        for (int k = i + 1; k < len; ++k)
502 >                            newElements[k-1] = elements[k];
503 >                        setArray(newElements);
504 >                        return true;
505 >                    } else
506 >                        newElements[i] = elements[i];
507 >                }
508 >
509 >                // special handling for last cell
510 >                if (eq(o, elements[newlen])) {
511 >                    setArray(newElements);
512 >                    return true;
513 >                }
514 >            }
515 >            return false;
516 >        } finally {
517 >            lock.unlock();
518 >        }
519      }
520  
521      /**
# Line 531 | Line 531 | public class CopyOnWriteArrayList<E>
531       *         (@code{fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
532       */
533      private void removeRange(int fromIndex, int toIndex) {
534 <        final ReentrantLock lock = this.lock;
535 <        lock.lock();
536 <        try {
537 <            Object[] elements = getArray();
538 <            int len = elements.length;
539 <
540 <            if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
541 <                throw new IndexOutOfBoundsException();
542 <            int newlen = len - (toIndex - fromIndex);
543 <            int numMoved = len - toIndex;
544 <            if (numMoved == 0)
545 <                setArray(Arrays.copyOf(elements, newlen));
546 <            else {
547 <                Object[] newElements = new Object[newlen];
548 <                System.arraycopy(elements, 0, newElements, 0, fromIndex);
549 <                System.arraycopy(elements, toIndex, newElements,
550 <                                 fromIndex, numMoved);
551 <                setArray(newElements);
552 <            }
553 <        } finally {
554 <            lock.unlock();
555 <        }
534 >        final ReentrantLock lock = this.lock;
535 >        lock.lock();
536 >        try {
537 >            Object[] elements = getArray();
538 >            int len = elements.length;
539 >
540 >            if (fromIndex < 0 || toIndex > len || toIndex < fromIndex)
541 >                throw new IndexOutOfBoundsException();
542 >            int newlen = len - (toIndex - fromIndex);
543 >            int numMoved = len - toIndex;
544 >            if (numMoved == 0)
545 >                setArray(Arrays.copyOf(elements, newlen));
546 >            else {
547 >                Object[] newElements = new Object[newlen];
548 >                System.arraycopy(elements, 0, newElements, 0, fromIndex);
549 >                System.arraycopy(elements, toIndex, newElements,
550 >                                 fromIndex, numMoved);
551 >                setArray(newElements);
552 >            }
553 >        } finally {
554 >            lock.unlock();
555 >        }
556      }
557  
558      /**
# Line 562 | Line 562 | public class CopyOnWriteArrayList<E>
562       * @return <tt>true</tt> if the element was added
563       */
564      public boolean addIfAbsent(E e) {
565 <        final ReentrantLock lock = this.lock;
566 <        lock.lock();
567 <        try {
568 <            // Copy while checking if already present.
569 <            // This wins in the most common case where it is not present
570 <            Object[] elements = getArray();
571 <            int len = elements.length;
572 <            Object[] newElements = new Object[len + 1];
573 <            for (int i = 0; i < len; ++i) {
574 <                if (eq(e, elements[i]))
575 <                    return false; // exit, throwing away copy
576 <                else
577 <                    newElements[i] = elements[i];
578 <            }
579 <            newElements[len] = e;
580 <            setArray(newElements);
581 <            return true;
582 <        } finally {
583 <            lock.unlock();
584 <        }
565 >        final ReentrantLock lock = this.lock;
566 >        lock.lock();
567 >        try {
568 >            // Copy while checking if already present.
569 >            // This wins in the most common case where it is not present
570 >            Object[] elements = getArray();
571 >            int len = elements.length;
572 >            Object[] newElements = new Object[len + 1];
573 >            for (int i = 0; i < len; ++i) {
574 >                if (eq(e, elements[i]))
575 >                    return false; // exit, throwing away copy
576 >                else
577 >                    newElements[i] = elements[i];
578 >            }
579 >            newElements[len] = e;
580 >            setArray(newElements);
581 >            return true;
582 >        } finally {
583 >            lock.unlock();
584 >        }
585      }
586  
587      /**
# Line 597 | Line 597 | public class CopyOnWriteArrayList<E>
597      public boolean containsAll(Collection<?> c) {
598          Object[] elements = getArray();
599          int len = elements.length;
600 <        for (Object e : c) {
600 >        for (Object e : c) {
601              if (indexOf(e, elements, 0, len) < 0)
602                  return false;
603 <        }
603 >        }
604          return true;
605      }
606  
# Line 619 | Line 619 | public class CopyOnWriteArrayList<E>
619       * @see #remove(Object)
620       */
621      public boolean removeAll(Collection<?> c) {
622 <        final ReentrantLock lock = this.lock;
623 <        lock.lock();
624 <        try {
625 <            Object[] elements = getArray();
626 <            int len = elements.length;
627 <            if (len != 0) {
628 <                // temp array holds those elements we know we want to keep
629 <                int newlen = 0;
630 <                Object[] temp = new Object[len];
631 <                for (int i = 0; i < len; ++i) {
632 <                    Object element = elements[i];
633 <                    if (!c.contains(element))
634 <                        temp[newlen++] = element;
635 <                }
636 <                if (newlen != len) {
637 <                    setArray(Arrays.copyOf(temp, newlen));
638 <                    return true;
639 <                }
640 <            }
641 <            return false;
642 <        } finally {
643 <            lock.unlock();
644 <        }
622 >        final ReentrantLock lock = this.lock;
623 >        lock.lock();
624 >        try {
625 >            Object[] elements = getArray();
626 >            int len = elements.length;
627 >            if (len != 0) {
628 >                // temp array holds those elements we know we want to keep
629 >                int newlen = 0;
630 >                Object[] temp = new Object[len];
631 >                for (int i = 0; i < len; ++i) {
632 >                    Object element = elements[i];
633 >                    if (!c.contains(element))
634 >                        temp[newlen++] = element;
635 >                }
636 >                if (newlen != len) {
637 >                    setArray(Arrays.copyOf(temp, newlen));
638 >                    return true;
639 >                }
640 >            }
641 >            return false;
642 >        } finally {
643 >            lock.unlock();
644 >        }
645      }
646  
647      /**
# Line 659 | Line 659 | public class CopyOnWriteArrayList<E>
659       * @see #remove(Object)
660       */
661      public boolean retainAll(Collection<?> c) {
662 <        final ReentrantLock lock = this.lock;
663 <        lock.lock();
664 <        try {
665 <            Object[] elements = getArray();
666 <            int len = elements.length;
667 <            if (len != 0) {
668 <                // temp array holds those elements we know we want to keep
669 <                int newlen = 0;
670 <                Object[] temp = new Object[len];
671 <                for (int i = 0; i < len; ++i) {
672 <                    Object element = elements[i];
673 <                    if (c.contains(element))
674 <                        temp[newlen++] = element;
675 <                }
676 <                if (newlen != len) {
677 <                    setArray(Arrays.copyOf(temp, newlen));
678 <                    return true;
679 <                }
680 <            }
681 <            return false;
682 <        } finally {
683 <            lock.unlock();
684 <        }
662 >        final ReentrantLock lock = this.lock;
663 >        lock.lock();
664 >        try {
665 >            Object[] elements = getArray();
666 >            int len = elements.length;
667 >            if (len != 0) {
668 >                // temp array holds those elements we know we want to keep
669 >                int newlen = 0;
670 >                Object[] temp = new Object[len];
671 >                for (int i = 0; i < len; ++i) {
672 >                    Object element = elements[i];
673 >                    if (c.contains(element))
674 >                        temp[newlen++] = element;
675 >                }
676 >                if (newlen != len) {
677 >                    setArray(Arrays.copyOf(temp, newlen));
678 >                    return true;
679 >                }
680 >            }
681 >            return false;
682 >        } finally {
683 >            lock.unlock();
684 >        }
685      }
686  
687      /**
# Line 696 | Line 696 | public class CopyOnWriteArrayList<E>
696       * @see #addIfAbsent(Object)
697       */
698      public int addAllAbsent(Collection<? extends E> c) {
699 <        Object[] cs = c.toArray();
700 <        if (cs.length == 0)
701 <            return 0;
702 <        Object[] uniq = new Object[cs.length];
703 <        final ReentrantLock lock = this.lock;
704 <        lock.lock();
705 <        try {
706 <            Object[] elements = getArray();
707 <            int len = elements.length;
708 <            int added = 0;
709 <            for (int i = 0; i < cs.length; ++i) { // scan for duplicates
710 <                Object e = cs[i];
711 <                if (indexOf(e, elements, 0, len) < 0 &&
712 <                    indexOf(e, uniq, 0, added) < 0)
713 <                    uniq[added++] = e;
714 <            }
715 <            if (added > 0) {
716 <                Object[] newElements = Arrays.copyOf(elements, len + added);
717 <                System.arraycopy(uniq, 0, newElements, len, added);
718 <                setArray(newElements);
719 <            }
720 <            return added;
721 <        } finally {
722 <            lock.unlock();
723 <        }
699 >        Object[] cs = c.toArray();
700 >        if (cs.length == 0)
701 >            return 0;
702 >        Object[] uniq = new Object[cs.length];
703 >        final ReentrantLock lock = this.lock;
704 >        lock.lock();
705 >        try {
706 >            Object[] elements = getArray();
707 >            int len = elements.length;
708 >            int added = 0;
709 >            for (int i = 0; i < cs.length; ++i) { // scan for duplicates
710 >                Object e = cs[i];
711 >                if (indexOf(e, elements, 0, len) < 0 &&
712 >                    indexOf(e, uniq, 0, added) < 0)
713 >                    uniq[added++] = e;
714 >            }
715 >            if (added > 0) {
716 >                Object[] newElements = Arrays.copyOf(elements, len + added);
717 >                System.arraycopy(uniq, 0, newElements, len, added);
718 >                setArray(newElements);
719 >            }
720 >            return added;
721 >        } finally {
722 >            lock.unlock();
723 >        }
724      }
725  
726      /**
# Line 728 | Line 728 | public class CopyOnWriteArrayList<E>
728       * The list will be empty after this call returns.
729       */
730      public void clear() {
731 <        final ReentrantLock lock = this.lock;
732 <        lock.lock();
733 <        try {
734 <            setArray(new Object[0]);
735 <        } finally {
736 <            lock.unlock();
737 <        }
731 >        final ReentrantLock lock = this.lock;
732 >        lock.lock();
733 >        try {
734 >            setArray(new Object[0]);
735 >        } finally {
736 >            lock.unlock();
737 >        }
738      }
739  
740      /**
# Line 748 | Line 748 | public class CopyOnWriteArrayList<E>
748       * @see #add(Object)
749       */
750      public boolean addAll(Collection<? extends E> c) {
751 <        Object[] cs = c.toArray();
752 <        if (cs.length == 0)
753 <            return false;
754 <        final ReentrantLock lock = this.lock;
755 <        lock.lock();
756 <        try {
757 <            Object[] elements = getArray();
758 <            int len = elements.length;
759 <            Object[] newElements = Arrays.copyOf(elements, len + cs.length);
760 <            System.arraycopy(cs, 0, newElements, len, cs.length);
761 <            setArray(newElements);
762 <            return true;
763 <        } finally {
764 <            lock.unlock();
765 <        }
751 >        Object[] cs = c.toArray();
752 >        if (cs.length == 0)
753 >            return false;
754 >        final ReentrantLock lock = this.lock;
755 >        lock.lock();
756 >        try {
757 >            Object[] elements = getArray();
758 >            int len = elements.length;
759 >            Object[] newElements = Arrays.copyOf(elements, len + cs.length);
760 >            System.arraycopy(cs, 0, newElements, len, cs.length);
761 >            setArray(newElements);
762 >            return true;
763 >        } finally {
764 >            lock.unlock();
765 >        }
766      }
767  
768      /**
# Line 782 | Line 782 | public class CopyOnWriteArrayList<E>
782       * @see #add(int,Object)
783       */
784      public boolean addAll(int index, Collection<? extends E> c) {
785 <        Object[] cs = c.toArray();
786 <        final ReentrantLock lock = this.lock;
787 <        lock.lock();
788 <        try {
789 <            Object[] elements = getArray();
790 <            int len = elements.length;
791 <            if (index > len || index < 0)
792 <                throw new IndexOutOfBoundsException("Index: "+index+
793 <                                                    ", Size: "+len);
794 <            if (cs.length == 0)
795 <                return false;
796 <            int numMoved = len - index;
797 <            Object[] newElements;
798 <            if (numMoved == 0)
799 <                newElements = Arrays.copyOf(elements, len + cs.length);
800 <            else {
801 <                newElements = new Object[len + cs.length];
802 <                System.arraycopy(elements, 0, newElements, 0, index);
803 <                System.arraycopy(elements, index,
804 <                                 newElements, index + cs.length,
805 <                                 numMoved);
806 <            }
807 <            System.arraycopy(cs, 0, newElements, index, cs.length);
808 <            setArray(newElements);
809 <            return true;
810 <        } finally {
811 <            lock.unlock();
812 <        }
785 >        Object[] cs = c.toArray();
786 >        final ReentrantLock lock = this.lock;
787 >        lock.lock();
788 >        try {
789 >            Object[] elements = getArray();
790 >            int len = elements.length;
791 >            if (index > len || index < 0)
792 >                throw new IndexOutOfBoundsException("Index: "+index+
793 >                                                    ", Size: "+len);
794 >            if (cs.length == 0)
795 >                return false;
796 >            int numMoved = len - index;
797 >            Object[] newElements;
798 >            if (numMoved == 0)
799 >                newElements = Arrays.copyOf(elements, len + cs.length);
800 >            else {
801 >                newElements = new Object[len + cs.length];
802 >                System.arraycopy(elements, 0, newElements, 0, index);
803 >                System.arraycopy(elements, index,
804 >                                 newElements, index + cs.length,
805 >                                 numMoved);
806 >            }
807 >            System.arraycopy(cs, 0, newElements, index, cs.length);
808 >            setArray(newElements);
809 >            return true;
810 >        } finally {
811 >            lock.unlock();
812 >        }
813      }
814  
815      /**
# Line 827 | Line 827 | public class CopyOnWriteArrayList<E>
827          s.defaultWriteObject();
828  
829          Object[] elements = getArray();
830 <        int len = elements.length;
830 >        int len = elements.length;
831          // Write out array length
832          s.writeInt(len);
833  
# Line 870 | Line 870 | public class CopyOnWriteArrayList<E>
870       * @return a string representation of this list
871       */
872      public String toString() {
873 <        return Arrays.toString(getArray());
873 >        return Arrays.toString(getArray());
874      }
875  
876      /**
# Line 895 | Line 895 | public class CopyOnWriteArrayList<E>
895              return false;
896  
897          List<?> list = (List<?>)(o);
898 <        Iterator<?> it = list.iterator();
899 <        Object[] elements = getArray();
900 <        int len = elements.length;
898 >        Iterator<?> it = list.iterator();
899 >        Object[] elements = getArray();
900 >        int len = elements.length;
901          for (int i = 0; i < len; ++i)
902              if (!it.hasNext() || !eq(elements[i], it.next()))
903                  return false;
# Line 915 | Line 915 | public class CopyOnWriteArrayList<E>
915       */
916      public int hashCode() {
917          int hashCode = 1;
918 <        Object[] elements = getArray();
919 <        int len = elements.length;
920 <        for (int i = 0; i < len; ++i) {
921 <            Object obj = elements[i];
918 >        Object[] elements = getArray();
919 >        int len = elements.length;
920 >        for (int i = 0; i < len; ++i) {
921 >            Object obj = elements[i];
922              hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
923          }
924          return hashCode;
# Line 988 | Line 988 | public class CopyOnWriteArrayList<E>
988              return cursor > 0;
989          }
990  
991 <        @SuppressWarnings("unchecked")
991 >        @SuppressWarnings("unchecked")
992          public E next() {
993 <            if (! hasNext())
993 >            if (! hasNext())
994                  throw new NoSuchElementException();
995 <            return (E) snapshot[cursor++];
995 >            return (E) snapshot[cursor++];
996          }
997  
998 <        @SuppressWarnings("unchecked")
998 >        @SuppressWarnings("unchecked")
999          public E previous() {
1000 <            if (! hasPrevious())
1000 >            if (! hasPrevious())
1001                  throw new NoSuchElementException();
1002 <            return (E) snapshot[--cursor];
1002 >            return (E) snapshot[--cursor];
1003          }
1004  
1005          public int nextIndex() {
# Line 1054 | Line 1054 | public class CopyOnWriteArrayList<E>
1054       * @throws IndexOutOfBoundsException {@inheritDoc}
1055       */
1056      public List<E> subList(int fromIndex, int toIndex) {
1057 <        final ReentrantLock lock = this.lock;
1058 <        lock.lock();
1059 <        try {
1060 <            Object[] elements = getArray();
1061 <            int len = elements.length;
1062 <            if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
1063 <                throw new IndexOutOfBoundsException();
1064 <            return new COWSubList<E>(this, fromIndex, toIndex);
1065 <        } finally {
1066 <            lock.unlock();
1067 <        }
1057 >        final ReentrantLock lock = this.lock;
1058 >        lock.lock();
1059 >        try {
1060 >            Object[] elements = getArray();
1061 >            int len = elements.length;
1062 >            if (fromIndex < 0 || toIndex > len || fromIndex > toIndex)
1063 >                throw new IndexOutOfBoundsException();
1064 >            return new COWSubList<E>(this, fromIndex, toIndex);
1065 >        } finally {
1066 >            lock.unlock();
1067 >        }
1068      }
1069  
1070      /**
# Line 1083 | Line 1083 | public class CopyOnWriteArrayList<E>
1083       * adding a bit more space/time doesn't seem even noticeable.
1084       */
1085      private static class COWSubList<E>
1086 <        extends AbstractList<E>
1087 <        implements RandomAccess
1086 >        extends AbstractList<E>
1087 >        implements RandomAccess
1088      {
1089          private final CopyOnWriteArrayList<E> l;
1090          private final int offset;
# Line 1093 | Line 1093 | public class CopyOnWriteArrayList<E>
1093  
1094          // only call this holding l's lock
1095          COWSubList(CopyOnWriteArrayList<E> list,
1096 <                   int fromIndex, int toIndex) {
1096 >                   int fromIndex, int toIndex) {
1097              l = list;
1098              expectedArray = l.getArray();
1099              offset = fromIndex;
# Line 1110 | Line 1110 | public class CopyOnWriteArrayList<E>
1110          private void rangeCheck(int index) {
1111              if (index<0 || index>=size)
1112                  throw new IndexOutOfBoundsException("Index: "+index+
1113 <                                                    ",Size: "+size);
1113 >                                                    ",Size: "+size);
1114          }
1115  
1116          public E set(int index, E element) {
1117 <            final ReentrantLock lock = l.lock;
1118 <            lock.lock();
1119 <            try {
1117 >            final ReentrantLock lock = l.lock;
1118 >            lock.lock();
1119 >            try {
1120                  rangeCheck(index);
1121                  checkForComodification();
1122                  E x = l.set(index+offset, element);
1123                  expectedArray = l.getArray();
1124                  return x;
1125 <            } finally {
1126 <                lock.unlock();
1127 <            }
1125 >            } finally {
1126 >                lock.unlock();
1127 >            }
1128          }
1129  
1130          public E get(int index) {
1131 <            final ReentrantLock lock = l.lock;
1132 <            lock.lock();
1133 <            try {
1131 >            final ReentrantLock lock = l.lock;
1132 >            lock.lock();
1133 >            try {
1134                  rangeCheck(index);
1135                  checkForComodification();
1136                  return l.get(index+offset);
1137 <            } finally {
1138 <                lock.unlock();
1139 <            }
1137 >            } finally {
1138 >                lock.unlock();
1139 >            }
1140          }
1141  
1142          public int size() {
1143 <            final ReentrantLock lock = l.lock;
1144 <            lock.lock();
1145 <            try {
1143 >            final ReentrantLock lock = l.lock;
1144 >            lock.lock();
1145 >            try {
1146                  checkForComodification();
1147                  return size;
1148 <            } finally {
1149 <                lock.unlock();
1150 <            }
1148 >            } finally {
1149 >                lock.unlock();
1150 >            }
1151          }
1152  
1153          public void add(int index, E element) {
1154 <            final ReentrantLock lock = l.lock;
1155 <            lock.lock();
1156 <            try {
1154 >            final ReentrantLock lock = l.lock;
1155 >            lock.lock();
1156 >            try {
1157                  checkForComodification();
1158                  if (index<0 || index>size)
1159                      throw new IndexOutOfBoundsException();
1160                  l.add(index+offset, element);
1161                  expectedArray = l.getArray();
1162                  size++;
1163 <            } finally {
1164 <                lock.unlock();
1165 <            }
1163 >            } finally {
1164 >                lock.unlock();
1165 >            }
1166          }
1167  
1168          public void clear() {
1169 <            final ReentrantLock lock = l.lock;
1170 <            lock.lock();
1171 <            try {
1169 >            final ReentrantLock lock = l.lock;
1170 >            lock.lock();
1171 >            try {
1172                  checkForComodification();
1173                  l.removeRange(offset, offset+size);
1174                  expectedArray = l.getArray();
1175                  size = 0;
1176 <            } finally {
1177 <                lock.unlock();
1178 <            }
1176 >            } finally {
1177 >                lock.unlock();
1178 >            }
1179          }
1180  
1181          public E remove(int index) {
1182 <            final ReentrantLock lock = l.lock;
1183 <            lock.lock();
1184 <            try {
1182 >            final ReentrantLock lock = l.lock;
1183 >            lock.lock();
1184 >            try {
1185                  rangeCheck(index);
1186                  checkForComodification();
1187                  E result = l.remove(index+offset);
1188                  expectedArray = l.getArray();
1189                  size--;
1190                  return result;
1191 <            } finally {
1192 <                lock.unlock();
1193 <            }
1191 >            } finally {
1192 >                lock.unlock();
1193 >            }
1194          }
1195  
1196          public boolean remove(Object o) {
1197 <            int index = indexOf(o);
1198 <            if (index == -1)
1199 <                return false;
1200 <            remove(index);
1201 <            return true;
1197 >            int index = indexOf(o);
1198 >            if (index == -1)
1199 >                return false;
1200 >            remove(index);
1201 >            return true;
1202          }
1203  
1204          public Iterator<E> iterator() {
1205 <            final ReentrantLock lock = l.lock;
1206 <            lock.lock();
1207 <            try {
1205 >            final ReentrantLock lock = l.lock;
1206 >            lock.lock();
1207 >            try {
1208                  checkForComodification();
1209                  return new COWSubListIterator<E>(l, 0, offset, size);
1210 <            } finally {
1211 <                lock.unlock();
1212 <            }
1210 >            } finally {
1211 >                lock.unlock();
1212 >            }
1213          }
1214  
1215          public ListIterator<E> listIterator(final int index) {
1216 <            final ReentrantLock lock = l.lock;
1217 <            lock.lock();
1218 <            try {
1216 >            final ReentrantLock lock = l.lock;
1217 >            lock.lock();
1218 >            try {
1219                  checkForComodification();
1220                  if (index<0 || index>size)
1221                      throw new IndexOutOfBoundsException("Index: "+index+
1222 <                                                        ", Size: "+size);
1222 >                                                        ", Size: "+size);
1223                  return new COWSubListIterator<E>(l, index, offset, size);
1224 <            } finally {
1225 <                lock.unlock();
1226 <            }
1224 >            } finally {
1225 >                lock.unlock();
1226 >            }
1227          }
1228  
1229          public List<E> subList(int fromIndex, int toIndex) {
1230 <            final ReentrantLock lock = l.lock;
1231 <            lock.lock();
1232 <            try {
1230 >            final ReentrantLock lock = l.lock;
1231 >            lock.lock();
1232 >            try {
1233                  checkForComodification();
1234                  if (fromIndex<0 || toIndex>size)
1235                      throw new IndexOutOfBoundsException();
1236                  return new COWSubList<E>(l, fromIndex + offset,
1237 <                                         toIndex + offset);
1238 <            } finally {
1239 <                lock.unlock();
1240 <            }
1237 >                                         toIndex + offset);
1238 >            } finally {
1239 >                lock.unlock();
1240 >            }
1241          }
1242  
1243      }
# Line 1249 | Line 1249 | public class CopyOnWriteArrayList<E>
1249          private final int offset;
1250          private final int size;
1251  
1252 <        COWSubListIterator(List<E> l, int index, int offset,
1253 <                           int size) {
1252 >        COWSubListIterator(List<E> l, int index, int offset,
1253 >                           int size) {
1254              this.index = index;
1255              this.offset = offset;
1256              this.size = size;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines