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.62 by dl, Tue Nov 22 11:48:06 2005 UTC vs.
Revision 1.63 by jsr166, Tue Nov 29 06:32:46 2005 UTC

# Line 70 | Line 70 | public class CopyOnWriteArrayList<E>
70       * Gets the array.  Non-private so as to also be accessible
71       * from CopyOnWriteArraySet class.
72       */
73 <    final Object[]  getArray() {
73 >    final Object[] getArray() {
74          return array;
75      }
76  
# 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[] a = c.toArray();
101 <        // If c.toArray incorrectly doesn't return Object[], copy it.
102 <        if (a.getClass() != Object[].class)
103 <            a = Arrays.copyOf(a, a.length, Object[].class);
104 <        setArray(a);
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 332 | Line 332 | public class CopyOnWriteArrayList<E>
332          Object[] elements = getArray();
333          int len = elements.length;
334          if (a.length < len)
335 <            return (T[]) Arrays.copyOf(elements, len, a.getClass());
336 <        else {
337 <            System.arraycopy(elements, 0, a, 0, len);
338 <            if (a.length > len)
339 <                a[len] = null;
340 <            return a;
341 <        }
335 >            return (T[]) Arrays.copyOf(elements, len, a.getClass());
336 >        else {
337 >            System.arraycopy(elements, 0, a, 0, len);
338 >            if (a.length > len)
339 >                a[len] = null;
340 >            return a;
341 >        }
342      }
343  
344      // Positional Access Operations
# Line 359 | Line 359 | public class CopyOnWriteArrayList<E>
359       * @throws IndexOutOfBoundsException {@inheritDoc}
360       */
361      public E set(int index, E element) {
362 <        final ReentrantLock lock = this.lock;
363 <        lock.lock();
364 <        try {
365 <            Object[] elements = getArray();
366 <            Object oldValue = elements[index];
367 <
368 <            if (oldValue != element) {
369 <                int len = elements.length;
370 <                Object[] newElements = Arrays.copyOf(elements, len);
371 <                newElements[index] = element;
372 <                setArray(newElements);
373 <            } else {
374 <                // Not quite a no-op; ensures volatile write semantics
375 <                setArray(elements);
376 <            }
377 <            return (E)oldValue;
378 <        } finally {
379 <            lock.unlock();
380 <        }
362 >        final ReentrantLock lock = this.lock;
363 >        lock.lock();
364 >        try {
365 >            Object[] elements = getArray();
366 >            Object oldValue = elements[index];
367 >
368 >            if (oldValue != element) {
369 >                int len = elements.length;
370 >                Object[] newElements = Arrays.copyOf(elements, len);
371 >                newElements[index] = element;
372 >                setArray(newElements);
373 >            } else {
374 >                // Not quite a no-op; ensures volatile write semantics
375 >                setArray(elements);
376 >            }
377 >            return (E)oldValue;
378 >        } finally {
379 >            lock.unlock();
380 >        }
381      }
382  
383      /**
# Line 387 | Line 387 | public class CopyOnWriteArrayList<E>
387       * @return <tt>true</tt> (as specified by {@link Collection#add})
388       */
389      public boolean add(E e) {
390 <        final ReentrantLock lock = this.lock;
391 <        lock.lock();
392 <        try {
393 <            Object[] elements = getArray();
394 <            int len = elements.length;
395 <            Object[] newElements = Arrays.copyOf(elements, len + 1);
396 <            newElements[len] = e;
397 <            setArray(newElements);
398 <            return true;
399 <        } finally {
400 <            lock.unlock();
401 <        }
390 >        final ReentrantLock lock = this.lock;
391 >        lock.lock();
392 >        try {
393 >            Object[] elements = getArray();
394 >            int len = elements.length;
395 >            Object[] newElements = Arrays.copyOf(elements, len + 1);
396 >            newElements[len] = e;
397 >            setArray(newElements);
398 >            return true;
399 >        } finally {
400 >            lock.unlock();
401 >        }
402      }
403  
404      /**
# Line 409 | Line 409 | public class CopyOnWriteArrayList<E>
409       * @throws IndexOutOfBoundsException {@inheritDoc}
410       */
411      public void add(int index, E element) {
412 <        final ReentrantLock lock = this.lock;
413 <        lock.lock();
414 <        try {
415 <            Object[] elements = getArray();
416 <            int len = elements.length;
417 <            if (index > len || index < 0)
418 <                throw new IndexOutOfBoundsException("Index: "+index+
419 <                                                    ", Size: "+len);
420 <            Object[] newElements;
421 <            int numMoved = len - index;
422 <            if (numMoved == 0)
423 <                newElements = Arrays.copyOf(elements, len + 1);
424 <            else {
425 <                newElements = new Object[len + 1];
426 <                System.arraycopy(elements, 0, newElements, 0, index);
427 <                System.arraycopy(elements, index, newElements, index + 1,
428 <                                 numMoved);
429 <            }
430 <            newElements[index] = element;
431 <            setArray(newElements);
432 <        } finally {
433 <            lock.unlock();
434 <        }
412 >        final ReentrantLock lock = this.lock;
413 >        lock.lock();
414 >        try {
415 >            Object[] elements = getArray();
416 >            int len = elements.length;
417 >            if (index > len || index < 0)
418 >                throw new IndexOutOfBoundsException("Index: "+index+
419 >                                                    ", Size: "+len);
420 >            Object[] newElements;
421 >            int numMoved = len - index;
422 >            if (numMoved == 0)
423 >                newElements = Arrays.copyOf(elements, len + 1);
424 >            else {
425 >                newElements = new Object[len + 1];
426 >                System.arraycopy(elements, 0, newElements, 0, index);
427 >                System.arraycopy(elements, index, newElements, index + 1,
428 >                                 numMoved);
429 >            }
430 >            newElements[index] = element;
431 >            setArray(newElements);
432 >        } finally {
433 >            lock.unlock();
434 >        }
435      }
436  
437      /**
# Line 442 | Line 442 | public class CopyOnWriteArrayList<E>
442       * @throws IndexOutOfBoundsException {@inheritDoc}
443       */
444      public E remove(int index) {
445 <        final ReentrantLock lock = this.lock;
446 <        lock.lock();
447 <        try {
448 <            Object[] elements = getArray();
449 <            int len = elements.length;
450 <            Object oldValue = elements[index];
451 <            int numMoved = len - index - 1;
452 <            if (numMoved == 0)
453 <                setArray(Arrays.copyOf(elements, len - 1));
454 <            else {
455 <                Object[] newElements = new Object[len - 1];
456 <                System.arraycopy(elements, 0, newElements, 0, index);
457 <                System.arraycopy(elements, index + 1, newElements, index,
458 <                                 numMoved);
459 <                setArray(newElements);
460 <            }
461 <            return (E)oldValue;
462 <        } finally {
463 <            lock.unlock();
464 <        }
445 >        final ReentrantLock lock = this.lock;
446 >        lock.lock();
447 >        try {
448 >            Object[] elements = getArray();
449 >            int len = elements.length;
450 >            Object oldValue = elements[index];
451 >            int numMoved = len - index - 1;
452 >            if (numMoved == 0)
453 >                setArray(Arrays.copyOf(elements, len - 1));
454 >            else {
455 >                Object[] newElements = new Object[len - 1];
456 >                System.arraycopy(elements, 0, newElements, 0, index);
457 >                System.arraycopy(elements, index + 1, newElements, index,
458 >                                 numMoved);
459 >                setArray(newElements);
460 >            }
461 >            return (E)oldValue;
462 >        } finally {
463 >            lock.unlock();
464 >        }
465      }
466  
467      /**
# Line 478 | Line 478 | public class CopyOnWriteArrayList<E>
478       * @return <tt>true</tt> if this list contained the specified element
479       */
480      public boolean remove(Object o) {
481 <        final ReentrantLock lock = this.lock;
482 <        lock.lock();
483 <        try {
484 <            Object[] elements = getArray();
485 <            int len = elements.length;
486 <            if (len != 0) {
487 <                // Copy while searching for element to remove
488 <                // This wins in the normal case of element being present
489 <                int newlen = len - 1;
490 <                Object[] newElements = new Object[newlen];
491 <
492 <                for (int i = 0; i < newlen; ++i) {
493 <                    if (eq(o, elements[i])) {
494 <                        // found one;  copy remaining and exit
495 <                        for (int k = i + 1; k < len; ++k)
496 <                            newElements[k-1] = elements[k];
497 <                        setArray(newElements);
498 <                        return true;
499 <                    } else
500 <                        newElements[i] = elements[i];
501 <                }
502 <
503 <                // special handling for last cell
504 <                if (eq(o, elements[newlen])) {
505 <                    setArray(newElements);
506 <                    return true;
507 <                }
508 <            }
509 <            return false;
510 <        } finally {
511 <            lock.unlock();
512 <        }
481 >        final ReentrantLock lock = this.lock;
482 >        lock.lock();
483 >        try {
484 >            Object[] elements = getArray();
485 >            int len = elements.length;
486 >            if (len != 0) {
487 >                // Copy while searching for element to remove
488 >                // This wins in the normal case of element being present
489 >                int newlen = len - 1;
490 >                Object[] newElements = new Object[newlen];
491 >
492 >                for (int i = 0; i < newlen; ++i) {
493 >                    if (eq(o, elements[i])) {
494 >                        // found one;  copy remaining and exit
495 >                        for (int k = i + 1; k < len; ++k)
496 >                            newElements[k-1] = elements[k];
497 >                        setArray(newElements);
498 >                        return true;
499 >                    } else
500 >                        newElements[i] = elements[i];
501 >                }
502 >
503 >                // special handling for last cell
504 >                if (eq(o, elements[newlen])) {
505 >                    setArray(newElements);
506 >                    return true;
507 >                }
508 >            }
509 >            return false;
510 >        } finally {
511 >            lock.unlock();
512 >        }
513      }
514  
515      /**
# Line 526 | Line 526 | public class CopyOnWriteArrayList<E>
526       *              &gt; size() || toIndex &lt; fromIndex)
527       */
528      private void removeRange(int fromIndex, int toIndex) {
529 <        final ReentrantLock lock = this.lock;
530 <        lock.lock();
531 <        try {
532 <            Object[] elements = getArray();
533 <            int len = elements.length;
534 <
535 <            if (fromIndex < 0 || fromIndex >= len ||
536 <                toIndex > len || toIndex < fromIndex)
537 <                throw new IndexOutOfBoundsException();
538 <            int newlen = len - (toIndex - fromIndex);
539 <            int numMoved = len - toIndex;
540 <            if (numMoved == 0)
541 <                setArray(Arrays.copyOf(elements, newlen));
542 <            else {
543 <                Object[] newElements = new Object[newlen];
544 <                System.arraycopy(elements, 0, newElements, 0, fromIndex);
545 <                System.arraycopy(elements, toIndex, newElements,
546 <                                 fromIndex, numMoved);
547 <                setArray(newElements);
548 <            }
549 <        } finally {
550 <            lock.unlock();
551 <        }
529 >        final ReentrantLock lock = this.lock;
530 >        lock.lock();
531 >        try {
532 >            Object[] elements = getArray();
533 >            int len = elements.length;
534 >
535 >            if (fromIndex < 0 || fromIndex >= len ||
536 >                toIndex > len || toIndex < fromIndex)
537 >                throw new IndexOutOfBoundsException();
538 >            int newlen = len - (toIndex - fromIndex);
539 >            int numMoved = len - toIndex;
540 >            if (numMoved == 0)
541 >                setArray(Arrays.copyOf(elements, newlen));
542 >            else {
543 >                Object[] newElements = new Object[newlen];
544 >                System.arraycopy(elements, 0, newElements, 0, fromIndex);
545 >                System.arraycopy(elements, toIndex, newElements,
546 >                                 fromIndex, numMoved);
547 >                setArray(newElements);
548 >            }
549 >        } finally {
550 >            lock.unlock();
551 >        }
552      }
553  
554      /**
# Line 558 | Line 558 | public class CopyOnWriteArrayList<E>
558       * @return <tt>true</tt> if the element was added
559       */
560      public boolean addIfAbsent(E e) {
561 <        final ReentrantLock lock = this.lock;
562 <        lock.lock();
563 <        try {
564 <            // Copy while checking if already present.
565 <            // This wins in the most common case where it is not present
566 <            Object[] elements = getArray();
567 <            int len = elements.length;
568 <            Object[] newElements = new Object[len + 1];
569 <            for (int i = 0; i < len; ++i) {
570 <                if (eq(e, elements[i]))
571 <                    return false; // exit, throwing away copy
572 <                else
573 <                    newElements[i] = elements[i];
574 <            }
575 <            newElements[len] = e;
576 <            setArray(newElements);
577 <            return true;
578 <        } finally {
579 <            lock.unlock();
580 <        }
561 >        final ReentrantLock lock = this.lock;
562 >        lock.lock();
563 >        try {
564 >            // Copy while checking if already present.
565 >            // This wins in the most common case where it is not present
566 >            Object[] elements = getArray();
567 >            int len = elements.length;
568 >            Object[] newElements = new Object[len + 1];
569 >            for (int i = 0; i < len; ++i) {
570 >                if (eq(e, elements[i]))
571 >                    return false; // exit, throwing away copy
572 >                else
573 >                    newElements[i] = elements[i];
574 >            }
575 >            newElements[len] = e;
576 >            setArray(newElements);
577 >            return true;
578 >        } finally {
579 >            lock.unlock();
580 >        }
581      }
582  
583      /**
# Line 593 | Line 593 | public class CopyOnWriteArrayList<E>
593      public boolean containsAll(Collection<?> c) {
594          Object[] elements = getArray();
595          int len = elements.length;
596 <        for (Object e : c) {
596 >        for (Object e : c) {
597              if (indexOf(e, elements, 0, len) < 0)
598                  return false;
599 <        }
599 >        }
600          return true;
601      }
602  
# Line 615 | Line 615 | public class CopyOnWriteArrayList<E>
615       * @see #remove(Object)
616       */
617      public boolean removeAll(Collection<?> c) {
618 <        final ReentrantLock lock = this.lock;
619 <        lock.lock();
620 <        try {
621 <            Object[] elements = getArray();
622 <            int len = elements.length;
623 <            if (len != 0) {
624 <                // temp array holds those elements we know we want to keep
625 <                int newlen = 0;
626 <                Object[] temp = new Object[len];
627 <                for (int i = 0; i < len; ++i) {
628 <                    Object element = elements[i];
629 <                    if (!c.contains(element))
630 <                        temp[newlen++] = element;
631 <                }
632 <                if (newlen != len) {
633 <                    setArray(Arrays.copyOf(temp, newlen));
634 <                    return true;
635 <                }
636 <            }
637 <            return false;
638 <        } finally {
639 <            lock.unlock();
640 <        }
618 >        final ReentrantLock lock = this.lock;
619 >        lock.lock();
620 >        try {
621 >            Object[] elements = getArray();
622 >            int len = elements.length;
623 >            if (len != 0) {
624 >                // temp array holds those elements we know we want to keep
625 >                int newlen = 0;
626 >                Object[] temp = new Object[len];
627 >                for (int i = 0; i < len; ++i) {
628 >                    Object element = elements[i];
629 >                    if (!c.contains(element))
630 >                        temp[newlen++] = element;
631 >                }
632 >                if (newlen != len) {
633 >                    setArray(Arrays.copyOf(temp, newlen));
634 >                    return true;
635 >                }
636 >            }
637 >            return false;
638 >        } finally {
639 >            lock.unlock();
640 >        }
641      }
642  
643      /**
# Line 655 | Line 655 | public class CopyOnWriteArrayList<E>
655       * @see #remove(Object)
656       */
657      public boolean retainAll(Collection<?> c) {
658 <        final ReentrantLock lock = this.lock;
659 <        lock.lock();
660 <        try {
661 <            Object[] elements = getArray();
662 <            int len = elements.length;
663 <            if (len != 0) {
664 <                // temp array holds those elements we know we want to keep
665 <                int newlen = 0;
666 <                Object[] temp = new Object[len];
667 <                for (int i = 0; i < len; ++i) {
668 <                    Object element = elements[i];
669 <                    if (c.contains(element))
670 <                        temp[newlen++] = element;
671 <                }
672 <                if (newlen != len) {
673 <                    setArray(Arrays.copyOf(temp, newlen));
674 <                    return true;
675 <                }
676 <            }
677 <            return false;
678 <        } finally {
679 <            lock.unlock();
680 <        }
658 >        final ReentrantLock lock = this.lock;
659 >        lock.lock();
660 >        try {
661 >            Object[] elements = getArray();
662 >            int len = elements.length;
663 >            if (len != 0) {
664 >                // temp array holds those elements we know we want to keep
665 >                int newlen = 0;
666 >                Object[] temp = new Object[len];
667 >                for (int i = 0; i < len; ++i) {
668 >                    Object element = elements[i];
669 >                    if (c.contains(element))
670 >                        temp[newlen++] = element;
671 >                }
672 >                if (newlen != len) {
673 >                    setArray(Arrays.copyOf(temp, newlen));
674 >                    return true;
675 >                }
676 >            }
677 >            return false;
678 >        } finally {
679 >            lock.unlock();
680 >        }
681      }
682  
683      /**
# Line 692 | Line 692 | public class CopyOnWriteArrayList<E>
692       * @see #addIfAbsent(Object)
693       */
694      public int addAllAbsent(Collection<? extends E> c) {
695 <        Object[] cs = c.toArray();
696 <        if (cs.length == 0)
697 <            return 0;
698 <        Object[] uniq = new Object[cs.length];
699 <        final ReentrantLock lock = this.lock;
700 <        lock.lock();
701 <        try {
702 <            Object[] elements = getArray();
703 <            int len = elements.length;
704 <            int added = 0;
705 <            for (int i = 0; i < cs.length; ++i) { // scan for duplicates
706 <                Object e = cs[i];
707 <                if (indexOf(e, elements, 0, len) < 0 &&
708 <                    indexOf(e, uniq, 0, added) < 0)
709 <                    uniq[added++] = e;
710 <            }
711 <            if (added > 0) {
712 <                Object[] newElements = Arrays.copyOf(elements, len + added);
713 <                System.arraycopy(uniq, 0, newElements, len, added);
714 <                setArray(newElements);
715 <            }
716 <            return added;
717 <        } finally {
718 <            lock.unlock();
719 <        }
695 >        Object[] cs = c.toArray();
696 >        if (cs.length == 0)
697 >            return 0;
698 >        Object[] uniq = new Object[cs.length];
699 >        final ReentrantLock lock = this.lock;
700 >        lock.lock();
701 >        try {
702 >            Object[] elements = getArray();
703 >            int len = elements.length;
704 >            int added = 0;
705 >            for (int i = 0; i < cs.length; ++i) { // scan for duplicates
706 >                Object e = cs[i];
707 >                if (indexOf(e, elements, 0, len) < 0 &&
708 >                    indexOf(e, uniq, 0, added) < 0)
709 >                    uniq[added++] = e;
710 >            }
711 >            if (added > 0) {
712 >                Object[] newElements = Arrays.copyOf(elements, len + added);
713 >                System.arraycopy(uniq, 0, newElements, len, added);
714 >                setArray(newElements);
715 >            }
716 >            return added;
717 >        } finally {
718 >            lock.unlock();
719 >        }
720      }
721  
722      /**
# Line 724 | Line 724 | public class CopyOnWriteArrayList<E>
724       * The list will be empty after this call returns.
725       */
726      public void clear() {
727 <        final ReentrantLock lock = this.lock;
728 <        lock.lock();
729 <        try {
730 <            setArray(new Object[0]);
731 <        } finally {
732 <            lock.unlock();
733 <        }
727 >        final ReentrantLock lock = this.lock;
728 >        lock.lock();
729 >        try {
730 >            setArray(new Object[0]);
731 >        } finally {
732 >            lock.unlock();
733 >        }
734      }
735  
736      /**
# Line 744 | Line 744 | public class CopyOnWriteArrayList<E>
744       * @see #add(Object)
745       */
746      public boolean addAll(Collection<? extends E> c) {
747 <        Object[] cs = c.toArray();
748 <        if (cs.length == 0)
749 <            return false;
750 <        final ReentrantLock lock = this.lock;
751 <        lock.lock();
752 <        try {
753 <            Object[] elements = getArray();
754 <            int len = elements.length;
755 <            Object[] newElements = Arrays.copyOf(elements, len + cs.length);
756 <            System.arraycopy(cs, 0, newElements, len, cs.length);
757 <            setArray(newElements);
758 <            return true;
759 <        } finally {
760 <            lock.unlock();
761 <        }
747 >        Object[] cs = c.toArray();
748 >        if (cs.length == 0)
749 >            return false;
750 >        final ReentrantLock lock = this.lock;
751 >        lock.lock();
752 >        try {
753 >            Object[] elements = getArray();
754 >            int len = elements.length;
755 >            Object[] newElements = Arrays.copyOf(elements, len + cs.length);
756 >            System.arraycopy(cs, 0, newElements, len, cs.length);
757 >            setArray(newElements);
758 >            return true;
759 >        } finally {
760 >            lock.unlock();
761 >        }
762      }
763  
764      /**
# Line 778 | Line 778 | public class CopyOnWriteArrayList<E>
778       * @see #add(int,Object)
779       */
780      public boolean addAll(int index, Collection<? extends E> c) {
781 <        Object[] cs = c.toArray();
782 <        final ReentrantLock lock = this.lock;
783 <        lock.lock();
784 <        try {
785 <            Object[] elements = getArray();
786 <            int len = elements.length;
787 <            if (index > len || index < 0)
788 <                throw new IndexOutOfBoundsException("Index: "+index+
789 <                                                    ", Size: "+len);
790 <            if (cs.length == 0)
791 <                return false;
792 <            int numMoved = len - index;
793 <            Object[] newElements;
794 <            if (numMoved == 0)
795 <                newElements = Arrays.copyOf(elements, len + cs.length);
796 <            else {
797 <                newElements = new Object[len + cs.length];
798 <                System.arraycopy(elements, 0, newElements, 0, index);
799 <                System.arraycopy(elements, index,
800 <                                 newElements, index + cs.length,
801 <                                 numMoved);
802 <            }
803 <            System.arraycopy(cs, 0, newElements, index, cs.length);
804 <            setArray(newElements);
805 <            return true;
806 <        } finally {
807 <            lock.unlock();
808 <        }
781 >        Object[] cs = c.toArray();
782 >        final ReentrantLock lock = this.lock;
783 >        lock.lock();
784 >        try {
785 >            Object[] elements = getArray();
786 >            int len = elements.length;
787 >            if (index > len || index < 0)
788 >                throw new IndexOutOfBoundsException("Index: "+index+
789 >                                                    ", Size: "+len);
790 >            if (cs.length == 0)
791 >                return false;
792 >            int numMoved = len - index;
793 >            Object[] newElements;
794 >            if (numMoved == 0)
795 >                newElements = Arrays.copyOf(elements, len + cs.length);
796 >            else {
797 >                newElements = new Object[len + cs.length];
798 >                System.arraycopy(elements, 0, newElements, 0, index);
799 >                System.arraycopy(elements, index,
800 >                                 newElements, index + cs.length,
801 >                                 numMoved);
802 >            }
803 >            System.arraycopy(cs, 0, newElements, index, cs.length);
804 >            setArray(newElements);
805 >            return true;
806 >        } finally {
807 >            lock.unlock();
808 >        }
809      }
810  
811      /**
# Line 823 | Line 823 | public class CopyOnWriteArrayList<E>
823          s.defaultWriteObject();
824  
825          Object[] elements = getArray();
826 <        int len = elements.length;
826 >        int len = elements.length;
827          // Write out array length
828          s.writeInt(len);
829  
# Line 866 | Line 866 | public class CopyOnWriteArrayList<E>
866       * @return a string representation of this list
867       */
868      public String toString() {
869 <        return Arrays.toString(getArray());
869 >        return Arrays.toString(getArray());
870      }
871  
872      /**
# Line 891 | Line 891 | public class CopyOnWriteArrayList<E>
891              return false;
892  
893          List<?> list = (List<?>)(o);
894 <        Iterator<?> it = list.iterator();
895 <        Object[] elements = getArray();
896 <        int len = elements.length;
894 >        Iterator<?> it = list.iterator();
895 >        Object[] elements = getArray();
896 >        int len = elements.length;
897          for (int i = 0; i < len; ++i)
898              if (!it.hasNext() || !eq(elements[i], it.next()))
899                  return false;
# Line 911 | Line 911 | public class CopyOnWriteArrayList<E>
911       */
912      public int hashCode() {
913          int hashCode = 1;
914 <        Object[] elements = getArray();
915 <        int len = elements.length;
916 <        for (int i = 0; i < len; ++i) {
917 <            Object obj = elements[i];
914 >        Object[] elements = getArray();
915 >        int len = elements.length;
916 >        for (int i = 0; i < len; ++i) {
917 >            Object obj = elements[i];
918              hashCode = 31*hashCode + (obj==null ? 0 : obj.hashCode());
919          }
920          return hashCode;
# Line 1057 | Line 1057 | public class CopyOnWriteArrayList<E>
1057       * @throws IndexOutOfBoundsException {@inheritDoc}
1058       */
1059      public List<E> subList(int fromIndex, int toIndex) {
1060 <        final ReentrantLock lock = this.lock;
1061 <        lock.lock();
1062 <        try {
1063 <            Object[] elements = getArray();
1064 <            int len = elements.length;
1065 <            if (fromIndex < 0 || toIndex > len  || fromIndex > toIndex)
1066 <                throw new IndexOutOfBoundsException();
1067 <            return new COWSubList<E>(this, fromIndex, toIndex);
1068 <        } finally {
1069 <            lock.unlock();
1070 <        }
1060 >        final ReentrantLock lock = this.lock;
1061 >        lock.lock();
1062 >        try {
1063 >            Object[] elements = getArray();
1064 >            int len = elements.length;
1065 >            if (fromIndex < 0 || toIndex > len  || fromIndex > toIndex)
1066 >                throw new IndexOutOfBoundsException();
1067 >            return new COWSubList<E>(this, fromIndex, toIndex);
1068 >        } finally {
1069 >            lock.unlock();
1070 >        }
1071      }
1072  
1073      /**
# Line 1093 | Line 1093 | public class CopyOnWriteArrayList<E>
1093  
1094          // only call this holding l's lock
1095          private 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 Iterator<E> iterator() {
1197 <            final ReentrantLock lock = l.lock;
1198 <            lock.lock();
1199 <            try {
1197 >            final ReentrantLock lock = l.lock;
1198 >            lock.lock();
1199 >            try {
1200                  checkForComodification();
1201                  return new COWSubListIterator<E>(l, 0, offset, size);
1202 <            } finally {
1203 <                lock.unlock();
1204 <            }
1202 >            } finally {
1203 >                lock.unlock();
1204 >            }
1205          }
1206  
1207          public ListIterator<E> listIterator(final int index) {
1208 <            final ReentrantLock lock = l.lock;
1209 <            lock.lock();
1210 <            try {
1208 >            final ReentrantLock lock = l.lock;
1209 >            lock.lock();
1210 >            try {
1211                  checkForComodification();
1212                  if (index<0 || index>size)
1213                      throw new IndexOutOfBoundsException("Index: "+index+
1214 <                                                        ", Size: "+size);
1214 >                                                        ", Size: "+size);
1215                  return new COWSubListIterator<E>(l, index, offset, size);
1216 <            } finally {
1217 <                lock.unlock();
1218 <            }
1216 >            } finally {
1217 >                lock.unlock();
1218 >            }
1219          }
1220  
1221          public List<E> subList(int fromIndex, int toIndex) {
1222 <            final ReentrantLock lock = l.lock;
1223 <            lock.lock();
1224 <            try {
1222 >            final ReentrantLock lock = l.lock;
1223 >            lock.lock();
1224 >            try {
1225                  checkForComodification();
1226                  if (fromIndex<0 || toIndex>size)
1227                      throw new IndexOutOfBoundsException();
1228                  return new COWSubList<E>(l, fromIndex + offset,
1229 <                                         toIndex + offset);
1230 <            } finally {
1231 <                lock.unlock();
1232 <            }
1229 >                                         toIndex + offset);
1230 >            } finally {
1231 >                lock.unlock();
1232 >            }
1233          }
1234  
1235      }
# Line 1241 | Line 1241 | public class CopyOnWriteArrayList<E>
1241          private final int offset;
1242          private final int size;
1243          private COWSubListIterator(List<E> l, int index, int offset,
1244 <                                   int size) {
1244 >                                   int size) {
1245              this.index = index;
1246              this.offset = offset;
1247              this.size = size;

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines