jdk/src/share/classes/java/util/concurrent/CopyOnWriteArrayList.java
changeset 18767 6214297bf27d
parent 17180 f568bc4ece21
child 19428 83f87aff7b07
equal deleted inserted replaced
18766:28c62f5e9a47 18767:6214297bf27d
     1 /*
     1 /*
     2  * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     2  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     3  *
     5  * This code is free software; you can redistribute it and/or modify it
     4  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     5  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.  Oracle designates this
     6  * published by the Free Software Foundation.  Oracle designates this
    32  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
    31  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
    33  * All rights reserved.
    32  * All rights reserved.
    34  */
    33  */
    35 
    34 
    36 package java.util.concurrent;
    35 package java.util.concurrent;
    37 import java.util.*;
    36 import java.util.AbstractList;
       
    37 import java.util.Arrays;
       
    38 import java.util.Collection;
       
    39 import java.util.Comparator;
       
    40 import java.util.ConcurrentModificationException;
       
    41 import java.util.Iterator;
       
    42 import java.util.List;
       
    43 import java.util.ListIterator;
       
    44 import java.util.NoSuchElementException;
       
    45 import java.util.Objects;
       
    46 import java.util.RandomAccess;
       
    47 import java.util.Spliterator;
       
    48 import java.util.Spliterators;
    38 import java.util.concurrent.locks.ReentrantLock;
    49 import java.util.concurrent.locks.ReentrantLock;
    39 import java.util.function.Consumer;
    50 import java.util.function.Consumer;
    40 import java.util.function.Predicate;
    51 import java.util.function.Predicate;
    41 import java.util.function.UnaryOperator;
    52 import java.util.function.UnaryOperator;
    42 
    53 
    43 /**
    54 /**
    44  * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
    55  * A thread-safe variant of {@link java.util.ArrayList} in which all mutative
    45  * operations (<tt>add</tt>, <tt>set</tt>, and so on) are implemented by
    56  * operations ({@code add}, {@code set}, and so on) are implemented by
    46  * making a fresh copy of the underlying array.
    57  * making a fresh copy of the underlying array.
    47  *
    58  *
    48  * <p> This is ordinarily too costly, but may be <em>more</em> efficient
    59  * <p>This is ordinarily too costly, but may be <em>more</em> efficient
    49  * than alternatives when traversal operations vastly outnumber
    60  * than alternatives when traversal operations vastly outnumber
    50  * mutations, and is useful when you cannot or don't want to
    61  * mutations, and is useful when you cannot or don't want to
    51  * synchronize traversals, yet need to preclude interference among
    62  * synchronize traversals, yet need to preclude interference among
    52  * concurrent threads.  The "snapshot" style iterator method uses a
    63  * concurrent threads.  The "snapshot" style iterator method uses a
    53  * reference to the state of the array at the point that the iterator
    64  * reference to the state of the array at the point that the iterator
    54  * was created. This array never changes during the lifetime of the
    65  * was created. This array never changes during the lifetime of the
    55  * iterator, so interference is impossible and the iterator is
    66  * iterator, so interference is impossible and the iterator is
    56  * guaranteed not to throw <tt>ConcurrentModificationException</tt>.
    67  * guaranteed not to throw {@code ConcurrentModificationException}.
    57  * The iterator will not reflect additions, removals, or changes to
    68  * The iterator will not reflect additions, removals, or changes to
    58  * the list since the iterator was created.  Element-changing
    69  * the list since the iterator was created.  Element-changing
    59  * operations on iterators themselves (<tt>remove</tt>, <tt>set</tt>, and
    70  * operations on iterators themselves ({@code remove}, {@code set}, and
    60  * <tt>add</tt>) are not supported. These methods throw
    71  * {@code add}) are not supported. These methods throw
    61  * <tt>UnsupportedOperationException</tt>.
    72  * {@code UnsupportedOperationException}.
    62  *
    73  *
    63  * <p>All elements are permitted, including <tt>null</tt>.
    74  * <p>All elements are permitted, including {@code null}.
    64  *
    75  *
    65  * <p>Memory consistency effects: As with other concurrent
    76  * <p>Memory consistency effects: As with other concurrent
    66  * collections, actions in a thread prior to placing an object into a
    77  * collections, actions in a thread prior to placing an object into a
    67  * {@code CopyOnWriteArrayList}
    78  * {@code CopyOnWriteArrayList}
    68  * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
    79  * <a href="package-summary.html#MemoryVisibility"><i>happen-before</i></a>
    80 public class CopyOnWriteArrayList<E>
    91 public class CopyOnWriteArrayList<E>
    81     implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    92     implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    82     private static final long serialVersionUID = 8673264195747942595L;
    93     private static final long serialVersionUID = 8673264195747942595L;
    83 
    94 
    84     /** The lock protecting all mutators */
    95     /** The lock protecting all mutators */
    85     transient final ReentrantLock lock = new ReentrantLock();
    96     final transient ReentrantLock lock = new ReentrantLock();
    86 
    97 
    87     /** The array, accessed only via getArray/setArray. */
    98     /** The array, accessed only via getArray/setArray. */
    88     private volatile transient Object[] array;
    99     private transient volatile Object[] array;
    89 
   100 
    90     /**
   101     /**
    91      * Gets the array.  Non-private so as to also be accessible
   102      * Gets the array.  Non-private so as to also be accessible
    92      * from CopyOnWriteArraySet class.
   103      * from CopyOnWriteArraySet class.
    93      */
   104      */
   116      *
   127      *
   117      * @param c the collection of initially held elements
   128      * @param c the collection of initially held elements
   118      * @throws NullPointerException if the specified collection is null
   129      * @throws NullPointerException if the specified collection is null
   119      */
   130      */
   120     public CopyOnWriteArrayList(Collection<? extends E> c) {
   131     public CopyOnWriteArrayList(Collection<? extends E> c) {
   121         Object[] elements = c.toArray();
   132         Object[] elements;
   122         // c.toArray might (incorrectly) not return Object[] (see 6260652)
   133         if (c.getClass() == CopyOnWriteArrayList.class)
   123         if (elements.getClass() != Object[].class)
   134             elements = ((CopyOnWriteArrayList<?>)c).getArray();
   124             elements = Arrays.copyOf(elements, elements.length, Object[].class);
   135         else {
       
   136             elements = c.toArray();
       
   137             // c.toArray might (incorrectly) not return Object[] (see 6260652)
       
   138             if (elements.getClass() != Object[].class)
       
   139                 elements = Arrays.copyOf(elements, elements.length, Object[].class);
       
   140         }
   125         setArray(elements);
   141         setArray(elements);
   126     }
   142     }
   127 
   143 
   128     /**
   144     /**
   129      * Creates a list holding a copy of the given array.
   145      * Creates a list holding a copy of the given array.
   144     public int size() {
   160     public int size() {
   145         return getArray().length;
   161         return getArray().length;
   146     }
   162     }
   147 
   163 
   148     /**
   164     /**
   149      * Returns <tt>true</tt> if this list contains no elements.
   165      * Returns {@code true} if this list contains no elements.
   150      *
   166      *
   151      * @return <tt>true</tt> if this list contains no elements
   167      * @return {@code true} if this list contains no elements
   152      */
   168      */
   153     public boolean isEmpty() {
   169     public boolean isEmpty() {
   154         return size() == 0;
   170         return size() == 0;
   155     }
   171     }
   156 
   172 
   157     /**
   173     /**
   158      * Tests for equality, coping with nulls.
   174      * Tests for equality, coping with nulls.
   159      */
   175      */
   160     private static boolean eq(Object o1, Object o2) {
   176     private static boolean eq(Object o1, Object o2) {
   161         return (o1 == null ? o2 == null : o1.equals(o2));
   177         return (o1 == null) ? o2 == null : o1.equals(o2);
   162     }
   178     }
   163 
   179 
   164     /**
   180     /**
   165      * static version of indexOf, to allow repeated calls without
   181      * static version of indexOf, to allow repeated calls without
   166      * needing to re-acquire array each time.
   182      * needing to re-acquire array each time.
   203         }
   219         }
   204         return -1;
   220         return -1;
   205     }
   221     }
   206 
   222 
   207     /**
   223     /**
   208      * Returns <tt>true</tt> if this list contains the specified element.
   224      * Returns {@code true} if this list contains the specified element.
   209      * More formally, returns <tt>true</tt> if and only if this list contains
   225      * More formally, returns {@code true} if and only if this list contains
   210      * at least one element <tt>e</tt> such that
   226      * at least one element {@code e} such that
   211      * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
   227      * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
   212      *
   228      *
   213      * @param o element whose presence in this list is to be tested
   229      * @param o element whose presence in this list is to be tested
   214      * @return <tt>true</tt> if this list contains the specified element
   230      * @return {@code true} if this list contains the specified element
   215      */
   231      */
   216     public boolean contains(Object o) {
   232     public boolean contains(Object o) {
   217         Object[] elements = getArray();
   233         Object[] elements = getArray();
   218         return indexOf(o, elements, 0, elements.length) >= 0;
   234         return indexOf(o, elements, 0, elements.length) >= 0;
   219     }
   235     }
   226         return indexOf(o, elements, 0, elements.length);
   242         return indexOf(o, elements, 0, elements.length);
   227     }
   243     }
   228 
   244 
   229     /**
   245     /**
   230      * Returns the index of the first occurrence of the specified element in
   246      * Returns the index of the first occurrence of the specified element in
   231      * this list, searching forwards from <tt>index</tt>, or returns -1 if
   247      * this list, searching forwards from {@code index}, or returns -1 if
   232      * the element is not found.
   248      * the element is not found.
   233      * More formally, returns the lowest index <tt>i</tt> such that
   249      * More formally, returns the lowest index {@code i} such that
   234      * <tt>(i&nbsp;&gt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
   250      * <tt>(i&nbsp;&gt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
   235      * or -1 if there is no such index.
   251      * or -1 if there is no such index.
   236      *
   252      *
   237      * @param e element to search for
   253      * @param e element to search for
   238      * @param index index to start searching from
   254      * @param index index to start searching from
   239      * @return the index of the first occurrence of the element in
   255      * @return the index of the first occurrence of the element in
   240      *         this list at position <tt>index</tt> or later in the list;
   256      *         this list at position {@code index} or later in the list;
   241      *         <tt>-1</tt> if the element is not found.
   257      *         {@code -1} if the element is not found.
   242      * @throws IndexOutOfBoundsException if the specified index is negative
   258      * @throws IndexOutOfBoundsException if the specified index is negative
   243      */
   259      */
   244     public int indexOf(E e, int index) {
   260     public int indexOf(E e, int index) {
   245         Object[] elements = getArray();
   261         Object[] elements = getArray();
   246         return indexOf(e, elements, index, elements.length);
   262         return indexOf(e, elements, index, elements.length);
   254         return lastIndexOf(o, elements, elements.length - 1);
   270         return lastIndexOf(o, elements, elements.length - 1);
   255     }
   271     }
   256 
   272 
   257     /**
   273     /**
   258      * Returns the index of the last occurrence of the specified element in
   274      * Returns the index of the last occurrence of the specified element in
   259      * this list, searching backwards from <tt>index</tt>, or returns -1 if
   275      * this list, searching backwards from {@code index}, or returns -1 if
   260      * the element is not found.
   276      * the element is not found.
   261      * More formally, returns the highest index <tt>i</tt> such that
   277      * More formally, returns the highest index {@code i} such that
   262      * <tt>(i&nbsp;&lt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
   278      * <tt>(i&nbsp;&lt;=&nbsp;index&nbsp;&amp;&amp;&nbsp;(e==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;e.equals(get(i))))</tt>,
   263      * or -1 if there is no such index.
   279      * or -1 if there is no such index.
   264      *
   280      *
   265      * @param e element to search for
   281      * @param e element to search for
   266      * @param index index to start searching backwards from
   282      * @param index index to start searching backwards from
   267      * @return the index of the last occurrence of the element at position
   283      * @return the index of the last occurrence of the element at position
   268      *         less than or equal to <tt>index</tt> in this list;
   284      *         less than or equal to {@code index} in this list;
   269      *         -1 if the element is not found.
   285      *         -1 if the element is not found.
   270      * @throws IndexOutOfBoundsException if the specified index is greater
   286      * @throws IndexOutOfBoundsException if the specified index is greater
   271      *         than or equal to the current size of this list
   287      *         than or equal to the current size of this list
   272      */
   288      */
   273     public int lastIndexOf(E e, int index) {
   289     public int lastIndexOf(E e, int index) {
   321      * the size of this list.
   337      * the size of this list.
   322      *
   338      *
   323      * <p>If this list fits in the specified array with room to spare
   339      * <p>If this list fits in the specified array with room to spare
   324      * (i.e., the array has more elements than this list), the element in
   340      * (i.e., the array has more elements than this list), the element in
   325      * the array immediately following the end of the list is set to
   341      * the array immediately following the end of the list is set to
   326      * <tt>null</tt>.  (This is useful in determining the length of this
   342      * {@code null}.  (This is useful in determining the length of this
   327      * list <i>only</i> if the caller knows that this list does not contain
   343      * list <i>only</i> if the caller knows that this list does not contain
   328      * any null elements.)
   344      * any null elements.)
   329      *
   345      *
   330      * <p>Like the {@link #toArray()} method, this method acts as bridge between
   346      * <p>Like the {@link #toArray()} method, this method acts as bridge between
   331      * array-based and collection-based APIs.  Further, this method allows
   347      * array-based and collection-based APIs.  Further, this method allows
   332      * precise control over the runtime type of the output array, and may,
   348      * precise control over the runtime type of the output array, and may,
   333      * under certain circumstances, be used to save allocation costs.
   349      * under certain circumstances, be used to save allocation costs.
   334      *
   350      *
   335      * <p>Suppose <tt>x</tt> is a list known to contain only strings.
   351      * <p>Suppose {@code x} is a list known to contain only strings.
   336      * The following code can be used to dump the list into a newly
   352      * The following code can be used to dump the list into a newly
   337      * allocated array of <tt>String</tt>:
   353      * allocated array of {@code String}:
   338      *
   354      *
   339      *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
   355      *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
   340      *
   356      *
   341      * Note that <tt>toArray(new Object[0])</tt> is identical in function to
   357      * Note that {@code toArray(new Object[0])} is identical in function to
   342      * <tt>toArray()</tt>.
   358      * {@code toArray()}.
   343      *
   359      *
   344      * @param a the array into which the elements of the list are to
   360      * @param a the array into which the elements of the list are to
   345      *          be stored, if it is big enough; otherwise, a new array of the
   361      *          be stored, if it is big enough; otherwise, a new array of the
   346      *          same runtime type is allocated for this purpose.
   362      *          same runtime type is allocated for this purpose.
   347      * @return an array containing all the elements in this list
   363      * @return an array containing all the elements in this list
   410 
   426 
   411     /**
   427     /**
   412      * Appends the specified element to the end of this list.
   428      * Appends the specified element to the end of this list.
   413      *
   429      *
   414      * @param e element to be appended to this list
   430      * @param e element to be appended to this list
   415      * @return <tt>true</tt> (as specified by {@link Collection#add})
   431      * @return {@code true} (as specified by {@link Collection#add})
   416      */
   432      */
   417     public boolean add(E e) {
   433     public boolean add(E e) {
   418         final ReentrantLock lock = this.lock;
   434         final ReentrantLock lock = this.lock;
   419         lock.lock();
   435         lock.lock();
   420         try {
   436         try {
   494 
   510 
   495     /**
   511     /**
   496      * Removes the first occurrence of the specified element from this list,
   512      * Removes the first occurrence of the specified element from this list,
   497      * if it is present.  If this list does not contain the element, it is
   513      * if it is present.  If this list does not contain the element, it is
   498      * unchanged.  More formally, removes the element with the lowest index
   514      * unchanged.  More formally, removes the element with the lowest index
   499      * <tt>i</tt> such that
   515      * {@code i} such that
   500      * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
   516      * <tt>(o==null&nbsp;?&nbsp;get(i)==null&nbsp;:&nbsp;o.equals(get(i)))</tt>
   501      * (if such an element exists).  Returns <tt>true</tt> if this list
   517      * (if such an element exists).  Returns {@code true} if this list
   502      * contained the specified element (or equivalently, if this list
   518      * contained the specified element (or equivalently, if this list
   503      * changed as a result of the call).
   519      * changed as a result of the call).
   504      *
   520      *
   505      * @param o element to be removed from this list, if present
   521      * @param o element to be removed from this list, if present
   506      * @return <tt>true</tt> if this list contained the specified element
   522      * @return {@code true} if this list contained the specified element
   507      */
   523      */
   508     public boolean remove(Object o) {
   524     public boolean remove(Object o) {
       
   525         Object[] snapshot = getArray();
       
   526         int index = indexOf(o, snapshot, 0, snapshot.length);
       
   527         return (index < 0) ? false : remove(o, snapshot, index);
       
   528     }
       
   529 
       
   530     /**
       
   531      * A version of remove(Object) using the strong hint that given
       
   532      * recent snapshot contains o at the given index.
       
   533      */
       
   534     private boolean remove(Object o, Object[] snapshot, int index) {
   509         final ReentrantLock lock = this.lock;
   535         final ReentrantLock lock = this.lock;
   510         lock.lock();
   536         lock.lock();
   511         try {
   537         try {
   512             Object[] elements = getArray();
   538             Object[] current = getArray();
   513             int len = elements.length;
   539             int len = current.length;
   514             if (len != 0) {
   540             if (snapshot != current) findIndex: {
   515                 // Copy while searching for element to remove
   541                 int prefix = Math.min(index, len);
   516                 // This wins in the normal case of element being present
   542                 for (int i = 0; i < prefix; i++) {
   517                 int newlen = len - 1;
   543                     if (current[i] != snapshot[i] && eq(o, current[i])) {
   518                 Object[] newElements = new Object[newlen];
   544                         index = i;
   519 
   545                         break findIndex;
   520                 for (int i = 0; i < newlen; ++i) {
   546                     }
   521                     if (eq(o, elements[i])) {
       
   522                         // found one;  copy remaining and exit
       
   523                         for (int k = i + 1; k < len; ++k)
       
   524                             newElements[k-1] = elements[k];
       
   525                         setArray(newElements);
       
   526                         return true;
       
   527                     } else
       
   528                         newElements[i] = elements[i];
       
   529                 }
   547                 }
   530 
   548                 if (index >= len)
   531                 // special handling for last cell
   549                     return false;
   532                 if (eq(o, elements[newlen])) {
   550                 if (current[index] == o)
   533                     setArray(newElements);
   551                     break findIndex;
   534                     return true;
   552                 index = indexOf(o, current, index, len);
   535                 }
   553                 if (index < 0)
   536             }
   554                     return false;
   537             return false;
   555             }
       
   556             Object[] newElements = new Object[len - 1];
       
   557             System.arraycopy(current, 0, newElements, 0, index);
       
   558             System.arraycopy(current, index + 1,
       
   559                              newElements, index,
       
   560                              len - index - 1);
       
   561             setArray(newElements);
       
   562             return true;
   538         } finally {
   563         } finally {
   539             lock.unlock();
   564             lock.unlock();
   540         }
   565         }
   541     }
   566     }
   542 
   567 
   543     /**
   568     /**
   544      * Removes from this list all of the elements whose index is between
   569      * Removes from this list all of the elements whose index is between
   545      * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
   570      * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
   546      * Shifts any succeeding elements to the left (reduces their index).
   571      * Shifts any succeeding elements to the left (reduces their index).
   547      * This call shortens the list by <tt>(toIndex - fromIndex)</tt> elements.
   572      * This call shortens the list by {@code (toIndex - fromIndex)} elements.
   548      * (If <tt>toIndex==fromIndex</tt>, this operation has no effect.)
   573      * (If {@code toIndex==fromIndex}, this operation has no effect.)
   549      *
   574      *
   550      * @param fromIndex index of first element to be removed
   575      * @param fromIndex index of first element to be removed
   551      * @param toIndex index after last element to be removed
   576      * @param toIndex index after last element to be removed
   552      * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range
   577      * @throws IndexOutOfBoundsException if fromIndex or toIndex out of range
   553      *         ({@code fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
   578      *         ({@code fromIndex < 0 || toIndex > size() || toIndex < fromIndex})
   579 
   604 
   580     /**
   605     /**
   581      * Appends the element, if not present.
   606      * Appends the element, if not present.
   582      *
   607      *
   583      * @param e element to be added to this list, if absent
   608      * @param e element to be added to this list, if absent
   584      * @return <tt>true</tt> if the element was added
   609      * @return {@code true} if the element was added
   585      */
   610      */
   586     public boolean addIfAbsent(E e) {
   611     public boolean addIfAbsent(E e) {
       
   612         Object[] snapshot = getArray();
       
   613         return indexOf(e, snapshot, 0, snapshot.length) >= 0 ? false :
       
   614             addIfAbsent(e, snapshot);
       
   615     }
       
   616 
       
   617     /**
       
   618      * A version of addIfAbsent using the strong hint that given
       
   619      * recent snapshot does not contain e.
       
   620      */
       
   621     private boolean addIfAbsent(E e, Object[] snapshot) {
   587         final ReentrantLock lock = this.lock;
   622         final ReentrantLock lock = this.lock;
   588         lock.lock();
   623         lock.lock();
   589         try {
   624         try {
   590             // Copy while checking if already present.
   625             Object[] current = getArray();
   591             // This wins in the most common case where it is not present
   626             int len = current.length;
   592             Object[] elements = getArray();
   627             if (snapshot != current) {
   593             int len = elements.length;
   628                 // Optimize for lost race to another addXXX operation
   594             Object[] newElements = new Object[len + 1];
   629                 int common = Math.min(snapshot.length, len);
   595             for (int i = 0; i < len; ++i) {
   630                 for (int i = 0; i < common; i++)
   596                 if (eq(e, elements[i]))
   631                     if (current[i] != snapshot[i] && eq(e, current[i]))
   597                     return false; // exit, throwing away copy
   632                         return false;
   598                 else
   633                 if (indexOf(e, current, common, len) >= 0)
   599                     newElements[i] = elements[i];
   634                         return false;
   600             }
   635             }
       
   636             Object[] newElements = Arrays.copyOf(current, len + 1);
   601             newElements[len] = e;
   637             newElements[len] = e;
   602             setArray(newElements);
   638             setArray(newElements);
   603             return true;
   639             return true;
   604         } finally {
   640         } finally {
   605             lock.unlock();
   641             lock.unlock();
   606         }
   642         }
   607     }
   643     }
   608 
   644 
   609     /**
   645     /**
   610      * Returns <tt>true</tt> if this list contains all of the elements of the
   646      * Returns {@code true} if this list contains all of the elements of the
   611      * specified collection.
   647      * specified collection.
   612      *
   648      *
   613      * @param c collection to be checked for containment in this list
   649      * @param c collection to be checked for containment in this list
   614      * @return <tt>true</tt> if this list contains all of the elements of the
   650      * @return {@code true} if this list contains all of the elements of the
   615      *         specified collection
   651      *         specified collection
   616      * @throws NullPointerException if the specified collection is null
   652      * @throws NullPointerException if the specified collection is null
   617      * @see #contains(Object)
   653      * @see #contains(Object)
   618      */
   654      */
   619     public boolean containsAll(Collection<?> c) {
   655     public boolean containsAll(Collection<?> c) {
   630      * Removes from this list all of its elements that are contained in
   666      * Removes from this list all of its elements that are contained in
   631      * the specified collection. This is a particularly expensive operation
   667      * the specified collection. This is a particularly expensive operation
   632      * in this class because of the need for an internal temporary array.
   668      * in this class because of the need for an internal temporary array.
   633      *
   669      *
   634      * @param c collection containing elements to be removed from this list
   670      * @param c collection containing elements to be removed from this list
   635      * @return <tt>true</tt> if this list changed as a result of the call
   671      * @return {@code true} if this list changed as a result of the call
   636      * @throws ClassCastException if the class of an element of this list
   672      * @throws ClassCastException if the class of an element of this list
   637      *         is incompatible with the specified collection
   673      *         is incompatible with the specified collection
   638      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
   674      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
   639      * @throws NullPointerException if this list contains a null element and the
   675      * @throws NullPointerException if this list contains a null element and the
   640      *         specified collection does not permit null elements
   676      *         specified collection does not permit null elements
   673      * Retains only the elements in this list that are contained in the
   709      * Retains only the elements in this list that are contained in the
   674      * specified collection.  In other words, removes from this list all of
   710      * specified collection.  In other words, removes from this list all of
   675      * its elements that are not contained in the specified collection.
   711      * its elements that are not contained in the specified collection.
   676      *
   712      *
   677      * @param c collection containing elements to be retained in this list
   713      * @param c collection containing elements to be retained in this list
   678      * @return <tt>true</tt> if this list changed as a result of the call
   714      * @return {@code true} if this list changed as a result of the call
   679      * @throws ClassCastException if the class of an element of this list
   715      * @throws ClassCastException if the class of an element of this list
   680      *         is incompatible with the specified collection
   716      *         is incompatible with the specified collection
   681      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
   717      *         (<a href="../Collection.html#optional-restrictions">optional</a>)
   682      * @throws NullPointerException if this list contains a null element and the
   718      * @throws NullPointerException if this list contains a null element and the
   683      *         specified collection does not permit null elements
   719      *         specified collection does not permit null elements
   725      */
   761      */
   726     public int addAllAbsent(Collection<? extends E> c) {
   762     public int addAllAbsent(Collection<? extends E> c) {
   727         Object[] cs = c.toArray();
   763         Object[] cs = c.toArray();
   728         if (cs.length == 0)
   764         if (cs.length == 0)
   729             return 0;
   765             return 0;
   730         Object[] uniq = new Object[cs.length];
       
   731         final ReentrantLock lock = this.lock;
   766         final ReentrantLock lock = this.lock;
   732         lock.lock();
   767         lock.lock();
   733         try {
   768         try {
   734             Object[] elements = getArray();
   769             Object[] elements = getArray();
   735             int len = elements.length;
   770             int len = elements.length;
   736             int added = 0;
   771             int added = 0;
   737             for (int i = 0; i < cs.length; ++i) { // scan for duplicates
   772             // uniquify and compact elements in cs
       
   773             for (int i = 0; i < cs.length; ++i) {
   738                 Object e = cs[i];
   774                 Object e = cs[i];
   739                 if (indexOf(e, elements, 0, len) < 0 &&
   775                 if (indexOf(e, elements, 0, len) < 0 &&
   740                     indexOf(e, uniq, 0, added) < 0)
   776                     indexOf(e, cs, 0, added) < 0)
   741                     uniq[added++] = e;
   777                     cs[added++] = e;
   742             }
   778             }
   743             if (added > 0) {
   779             if (added > 0) {
   744                 Object[] newElements = Arrays.copyOf(elements, len + added);
   780                 Object[] newElements = Arrays.copyOf(elements, len + added);
   745                 System.arraycopy(uniq, 0, newElements, len, added);
   781                 System.arraycopy(cs, 0, newElements, len, added);
   746                 setArray(newElements);
   782                 setArray(newElements);
   747             }
   783             }
   748             return added;
   784             return added;
   749         } finally {
   785         } finally {
   750             lock.unlock();
   786             lock.unlock();
   769      * Appends all of the elements in the specified collection to the end
   805      * Appends all of the elements in the specified collection to the end
   770      * of this list, in the order that they are returned by the specified
   806      * of this list, in the order that they are returned by the specified
   771      * collection's iterator.
   807      * collection's iterator.
   772      *
   808      *
   773      * @param c collection containing elements to be added to this list
   809      * @param c collection containing elements to be added to this list
   774      * @return <tt>true</tt> if this list changed as a result of the call
   810      * @return {@code true} if this list changed as a result of the call
   775      * @throws NullPointerException if the specified collection is null
   811      * @throws NullPointerException if the specified collection is null
   776      * @see #add(Object)
   812      * @see #add(Object)
   777      */
   813      */
   778     public boolean addAll(Collection<? extends E> c) {
   814     public boolean addAll(Collection<? extends E> c) {
   779         Object[] cs = c.toArray();
   815         Object[] cs = (c.getClass() == CopyOnWriteArrayList.class) ?
       
   816             ((CopyOnWriteArrayList<?>)c).getArray() : c.toArray();
   780         if (cs.length == 0)
   817         if (cs.length == 0)
   781             return false;
   818             return false;
   782         final ReentrantLock lock = this.lock;
   819         final ReentrantLock lock = this.lock;
   783         lock.lock();
   820         lock.lock();
   784         try {
   821         try {
   785             Object[] elements = getArray();
   822             Object[] elements = getArray();
   786             int len = elements.length;
   823             int len = elements.length;
   787             Object[] newElements = Arrays.copyOf(elements, len + cs.length);
   824             if (len == 0 && cs.getClass() == Object[].class)
   788             System.arraycopy(cs, 0, newElements, len, cs.length);
   825                 setArray(cs);
   789             setArray(newElements);
   826             else {
       
   827                 Object[] newElements = Arrays.copyOf(elements, len + cs.length);
       
   828                 System.arraycopy(cs, 0, newElements, len, cs.length);
       
   829                 setArray(newElements);
       
   830             }
   790             return true;
   831             return true;
   791         } finally {
   832         } finally {
   792             lock.unlock();
   833             lock.unlock();
   793         }
   834         }
   794     }
   835     }
   802      * specified collection's iterator.
   843      * specified collection's iterator.
   803      *
   844      *
   804      * @param index index at which to insert the first element
   845      * @param index index at which to insert the first element
   805      *        from the specified collection
   846      *        from the specified collection
   806      * @param c collection containing elements to be added to this list
   847      * @param c collection containing elements to be added to this list
   807      * @return <tt>true</tt> if this list changed as a result of the call
   848      * @return {@code true} if this list changed as a result of the call
   808      * @throws IndexOutOfBoundsException {@inheritDoc}
   849      * @throws IndexOutOfBoundsException {@inheritDoc}
   809      * @throws NullPointerException if the specified collection is null
   850      * @throws NullPointerException if the specified collection is null
   810      * @see #add(int,Object)
   851      * @see #add(int,Object)
   811      */
   852      */
   812     public boolean addAll(int index, Collection<? extends E> c) {
   853     public boolean addAll(int index, Collection<? extends E> c) {
   838         } finally {
   879         } finally {
   839             lock.unlock();
   880             lock.unlock();
   840         }
   881         }
   841     }
   882     }
   842 
   883 
       
   884     public void forEach(Consumer<? super E> action) {
       
   885         if (action == null) throw new NullPointerException();
       
   886         Object[] elements = getArray();
       
   887         int len = elements.length;
       
   888         for (int i = 0; i < len; ++i) {
       
   889             @SuppressWarnings("unchecked") E e = (E) elements[i];
       
   890             action.accept(e);
       
   891         }
       
   892     }
       
   893 
       
   894     public boolean removeIf(Predicate<? super E> filter) {
       
   895         if (filter == null) throw new NullPointerException();
       
   896         final ReentrantLock lock = this.lock;
       
   897         lock.lock();
       
   898         try {
       
   899             Object[] elements = getArray();
       
   900             int len = elements.length;
       
   901             if (len != 0) {
       
   902                 int newlen = 0;
       
   903                 Object[] temp = new Object[len];
       
   904                 for (int i = 0; i < len; ++i) {
       
   905                     @SuppressWarnings("unchecked") E e = (E) elements[i];
       
   906                     if (!filter.test(e))
       
   907                         temp[newlen++] = e;
       
   908                 }
       
   909                 if (newlen != len) {
       
   910                     setArray(Arrays.copyOf(temp, newlen));
       
   911                     return true;
       
   912                 }
       
   913             }
       
   914             return false;
       
   915         } finally {
       
   916             lock.unlock();
       
   917         }
       
   918     }
       
   919 
       
   920     public void replaceAll(UnaryOperator<E> operator) {
       
   921         if (operator == null) throw new NullPointerException();
       
   922         final ReentrantLock lock = this.lock;
       
   923         lock.lock();
       
   924         try {
       
   925             Object[] elements = getArray();
       
   926             int len = elements.length;
       
   927             Object[] newElements = Arrays.copyOf(elements, len);
       
   928             for (int i = 0; i < len; ++i) {
       
   929                 @SuppressWarnings("unchecked") E e = (E) elements[i];
       
   930                 newElements[i] = operator.apply(e);
       
   931             }
       
   932             setArray(newElements);
       
   933         } finally {
       
   934             lock.unlock();
       
   935         }
       
   936     }
       
   937 
       
   938     public void sort(Comparator<? super E> c) {
       
   939         final ReentrantLock lock = this.lock;
       
   940         lock.lock();
       
   941         try {
       
   942             Object[] elements = getArray();
       
   943             Object[] newElements = Arrays.copyOf(elements, elements.length);
       
   944             @SuppressWarnings("unchecked") E[] es = (E[])newElements;
       
   945             Arrays.sort(es, c);
       
   946             setArray(newElements);
       
   947         } finally {
       
   948             lock.unlock();
       
   949         }
       
   950     }
       
   951 
   843     /**
   952     /**
   844      * Saves this list to a stream (that is, serializes it).
   953      * Saves this list to a stream (that is, serializes it).
   845      *
   954      *
   846      * @serialData The length of the array backing the list is emitted
   955      * @serialData The length of the array backing the list is emitted
   847      *               (int), followed by all of its elements (each an Object)
   956      *               (int), followed by all of its elements (each an Object)
   884 
   993 
   885     /**
   994     /**
   886      * Returns a string representation of this list.  The string
   995      * Returns a string representation of this list.  The string
   887      * representation consists of the string representations of the list's
   996      * representation consists of the string representations of the list's
   888      * elements in the order they are returned by its iterator, enclosed in
   997      * elements in the order they are returned by its iterator, enclosed in
   889      * square brackets (<tt>"[]"</tt>).  Adjacent elements are separated by
   998      * square brackets ({@code "[]"}).  Adjacent elements are separated by
   890      * the characters <tt>", "</tt> (comma and space).  Elements are
   999      * the characters {@code ", "} (comma and space).  Elements are
   891      * converted to strings as by {@link String#valueOf(Object)}.
  1000      * converted to strings as by {@link String#valueOf(Object)}.
   892      *
  1001      *
   893      * @return a string representation of this list
  1002      * @return a string representation of this list
   894      */
  1003      */
   895     public String toString() {
  1004     public String toString() {
   951      * Returns an iterator over the elements in this list in proper sequence.
  1060      * Returns an iterator over the elements in this list in proper sequence.
   952      *
  1061      *
   953      * <p>The returned iterator provides a snapshot of the state of the list
  1062      * <p>The returned iterator provides a snapshot of the state of the list
   954      * when the iterator was constructed. No synchronization is needed while
  1063      * when the iterator was constructed. No synchronization is needed while
   955      * traversing the iterator. The iterator does <em>NOT</em> support the
  1064      * traversing the iterator. The iterator does <em>NOT</em> support the
   956      * <tt>remove</tt> method.
  1065      * {@code remove} method.
   957      *
  1066      *
   958      * @return an iterator over the elements in this list in proper sequence
  1067      * @return an iterator over the elements in this list in proper sequence
   959      */
  1068      */
   960     public Iterator<E> iterator() {
  1069     public Iterator<E> iterator() {
   961         return new COWIterator<E>(getArray(), 0);
  1070         return new COWIterator<E>(getArray(), 0);
   965      * {@inheritDoc}
  1074      * {@inheritDoc}
   966      *
  1075      *
   967      * <p>The returned iterator provides a snapshot of the state of the list
  1076      * <p>The returned iterator provides a snapshot of the state of the list
   968      * when the iterator was constructed. No synchronization is needed while
  1077      * when the iterator was constructed. No synchronization is needed while
   969      * traversing the iterator. The iterator does <em>NOT</em> support the
  1078      * traversing the iterator. The iterator does <em>NOT</em> support the
   970      * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
  1079      * {@code remove}, {@code set} or {@code add} methods.
   971      */
  1080      */
   972     public ListIterator<E> listIterator() {
  1081     public ListIterator<E> listIterator() {
   973         return new COWIterator<E>(getArray(), 0);
  1082         return new COWIterator<E>(getArray(), 0);
   974     }
  1083     }
   975 
  1084 
   977      * {@inheritDoc}
  1086      * {@inheritDoc}
   978      *
  1087      *
   979      * <p>The returned iterator provides a snapshot of the state of the list
  1088      * <p>The returned iterator provides a snapshot of the state of the list
   980      * when the iterator was constructed. No synchronization is needed while
  1089      * when the iterator was constructed. No synchronization is needed while
   981      * traversing the iterator. The iterator does <em>NOT</em> support the
  1090      * traversing the iterator. The iterator does <em>NOT</em> support the
   982      * <tt>remove</tt>, <tt>set</tt> or <tt>add</tt> methods.
  1091      * {@code remove}, {@code set} or {@code add} methods.
   983      *
  1092      *
   984      * @throws IndexOutOfBoundsException {@inheritDoc}
  1093      * @throws IndexOutOfBoundsException {@inheritDoc}
   985      */
  1094      */
   986     public ListIterator<E> listIterator(final int index) {
  1095     public ListIterator<E> listIterator(final int index) {
   987         Object[] elements = getArray();
  1096         Object[] elements = getArray();
   990             throw new IndexOutOfBoundsException("Index: "+index);
  1099             throw new IndexOutOfBoundsException("Index: "+index);
   991 
  1100 
   992         return new COWIterator<E>(elements, index);
  1101         return new COWIterator<E>(elements, index);
   993     }
  1102     }
   994 
  1103 
   995     private static class COWIterator<E> implements ListIterator<E> {
  1104     public Spliterator<E> spliterator() {
       
  1105         return Spliterators.spliterator
       
  1106             (getArray(), Spliterator.IMMUTABLE | Spliterator.ORDERED);
       
  1107     }
       
  1108 
       
  1109     static final class COWIterator<E> implements ListIterator<E> {
   996         /** Snapshot of the array */
  1110         /** Snapshot of the array */
   997         private final Object[] snapshot;
  1111         private final Object[] snapshot;
   998         /** Index of element to be returned by subsequent call to next.  */
  1112         /** Index of element to be returned by subsequent call to next.  */
   999         private int cursor;
  1113         private int cursor;
  1000 
  1114 
  1033             return cursor-1;
  1147             return cursor-1;
  1034         }
  1148         }
  1035 
  1149 
  1036         /**
  1150         /**
  1037          * Not supported. Always throws UnsupportedOperationException.
  1151          * Not supported. Always throws UnsupportedOperationException.
  1038          * @throws UnsupportedOperationException always; <tt>remove</tt>
  1152          * @throws UnsupportedOperationException always; {@code remove}
  1039          *         is not supported by this iterator.
  1153          *         is not supported by this iterator.
  1040          */
  1154          */
  1041         public void remove() {
  1155         public void remove() {
  1042             throw new UnsupportedOperationException();
  1156             throw new UnsupportedOperationException();
  1043         }
  1157         }
  1044 
  1158 
  1045         /**
  1159         /**
  1046          * Not supported. Always throws UnsupportedOperationException.
  1160          * Not supported. Always throws UnsupportedOperationException.
  1047          * @throws UnsupportedOperationException always; <tt>set</tt>
  1161          * @throws UnsupportedOperationException always; {@code set}
  1048          *         is not supported by this iterator.
  1162          *         is not supported by this iterator.
  1049          */
  1163          */
  1050         public void set(E e) {
  1164         public void set(E e) {
  1051             throw new UnsupportedOperationException();
  1165             throw new UnsupportedOperationException();
  1052         }
  1166         }
  1053 
  1167 
  1054         /**
  1168         /**
  1055          * Not supported. Always throws UnsupportedOperationException.
  1169          * Not supported. Always throws UnsupportedOperationException.
  1056          * @throws UnsupportedOperationException always; <tt>add</tt>
  1170          * @throws UnsupportedOperationException always; {@code add}
  1057          *         is not supported by this iterator.
  1171          *         is not supported by this iterator.
  1058          */
  1172          */
  1059         public void add(E e) {
  1173         public void add(E e) {
  1060             throw new UnsupportedOperationException();
  1174             throw new UnsupportedOperationException();
  1061         }
  1175         }
  1062 
  1176 
  1063         @Override
  1177         @Override
  1064         @SuppressWarnings("unchecked")
       
  1065         public void forEachRemaining(Consumer<? super E> action) {
  1178         public void forEachRemaining(Consumer<? super E> action) {
  1066             Objects.requireNonNull(action);
  1179             Objects.requireNonNull(action);
  1067             final int size = snapshot.length;
  1180             Object[] elements = snapshot;
  1068             for (int i=cursor; i < size; i++) {
  1181             final int size = elements.length;
  1069                 action.accept((E) snapshot[i]);
  1182             for (int i = cursor; i < size; i++) {
       
  1183                 @SuppressWarnings("unchecked") E e = (E) elements[i];
       
  1184                 action.accept(e);
  1070             }
  1185             }
  1071             cursor = size;
  1186             cursor = size;
  1072         }
  1187         }
  1073     }
  1188     }
  1074 
  1189 
  1075     /**
  1190     /**
  1076      * Returns a view of the portion of this list between
  1191      * Returns a view of the portion of this list between
  1077      * <tt>fromIndex</tt>, inclusive, and <tt>toIndex</tt>, exclusive.
  1192      * {@code fromIndex}, inclusive, and {@code toIndex}, exclusive.
  1078      * The returned list is backed by this list, so changes in the
  1193      * The returned list is backed by this list, so changes in the
  1079      * returned list are reflected in this list.
  1194      * returned list are reflected in this list.
  1080      *
  1195      *
  1081      * <p>The semantics of the list returned by this method become
  1196      * <p>The semantics of the list returned by this method become
  1082      * undefined if the backing list (i.e., this list) is modified in
  1197      * undefined if the backing list (i.e., this list) is modified in
  1272             } finally {
  1387             } finally {
  1273                 lock.unlock();
  1388                 lock.unlock();
  1274             }
  1389             }
  1275         }
  1390         }
  1276 
  1391 
  1277         @Override
       
  1278         public void forEach(Consumer<? super E> action) {
  1392         public void forEach(Consumer<? super E> action) {
  1279             @SuppressWarnings("unchecked")
  1393             if (action == null) throw new NullPointerException();
  1280             final E[] elements = (E[]) l.getArray();
  1394             int lo = offset;
  1281             checkForComodification();
  1395             int hi = offset + size;
  1282             l.forEach(action, elements, offset, offset + size);
  1396             Object[] a = expectedArray;
  1283         }
  1397             if (l.getArray() != a)
  1284 
  1398                 throw new ConcurrentModificationException();
  1285         @Override
  1399             if (lo < 0 || hi > a.length)
       
  1400                 throw new IndexOutOfBoundsException();
       
  1401             for (int i = lo; i < hi; ++i) {
       
  1402                 @SuppressWarnings("unchecked") E e = (E) a[i];
       
  1403                 action.accept(e);
       
  1404             }
       
  1405         }
       
  1406 
       
  1407         public void replaceAll(UnaryOperator<E> operator) {
       
  1408             if (operator == null) throw new NullPointerException();
       
  1409             final ReentrantLock lock = l.lock;
       
  1410             lock.lock();
       
  1411             try {
       
  1412                 int lo = offset;
       
  1413                 int hi = offset + size;
       
  1414                 Object[] elements = expectedArray;
       
  1415                 if (l.getArray() != elements)
       
  1416                     throw new ConcurrentModificationException();
       
  1417                 int len = elements.length;
       
  1418                 if (lo < 0 || hi > len)
       
  1419                     throw new IndexOutOfBoundsException();
       
  1420                 Object[] newElements = Arrays.copyOf(elements, len);
       
  1421                 for (int i = lo; i < hi; ++i) {
       
  1422                     @SuppressWarnings("unchecked") E e = (E) elements[i];
       
  1423                     newElements[i] = operator.apply(e);
       
  1424                 }
       
  1425                 l.setArray(expectedArray = newElements);
       
  1426             } finally {
       
  1427                 lock.unlock();
       
  1428             }
       
  1429         }
       
  1430 
  1286         public void sort(Comparator<? super E> c) {
  1431         public void sort(Comparator<? super E> c) {
  1287             final ReentrantLock lock = l.lock;
  1432             final ReentrantLock lock = l.lock;
  1288             lock.lock();
  1433             lock.lock();
  1289             try {
  1434             try {
  1290                 checkForComodification();
  1435                 int lo = offset;
  1291                 l.sort(c, offset, offset + size);
  1436                 int hi = offset + size;
  1292                 expectedArray = l.getArray();
  1437                 Object[] elements = expectedArray;
       
  1438                 if (l.getArray() != elements)
       
  1439                     throw new ConcurrentModificationException();
       
  1440                 int len = elements.length;
       
  1441                 if (lo < 0 || hi > len)
       
  1442                     throw new IndexOutOfBoundsException();
       
  1443                 Object[] newElements = Arrays.copyOf(elements, len);
       
  1444                 @SuppressWarnings("unchecked") E[] es = (E[])newElements;
       
  1445                 Arrays.sort(es, lo, hi, c);
       
  1446                 l.setArray(expectedArray = newElements);
  1293             } finally {
  1447             } finally {
  1294                 lock.unlock();
  1448                 lock.unlock();
  1295             }
  1449             }
  1296         }
  1450         }
  1297 
  1451 
  1298         @Override
  1452         public boolean removeAll(Collection<?> c) {
  1299         public boolean removeIf(Predicate<? super E> filter) {
  1453             if (c == null) throw new NullPointerException();
  1300             Objects.requireNonNull(filter);
  1454             boolean removed = false;
  1301             final ReentrantLock lock = l.lock;
  1455             final ReentrantLock lock = l.lock;
  1302             lock.lock();
  1456             lock.lock();
  1303             try {
  1457             try {
  1304                 checkForComodification();
  1458                 int n = size;
  1305                 final int removeCount =
  1459                 if (n > 0) {
  1306                         l.removeIf(filter, offset, offset + size);
  1460                     int lo = offset;
  1307                 expectedArray = l.getArray();
  1461                     int hi = offset + n;
  1308                 size -= removeCount;
  1462                     Object[] elements = expectedArray;
  1309                 return removeCount > 0;
  1463                     if (l.getArray() != elements)
       
  1464                         throw new ConcurrentModificationException();
       
  1465                     int len = elements.length;
       
  1466                     if (lo < 0 || hi > len)
       
  1467                         throw new IndexOutOfBoundsException();
       
  1468                     int newSize = 0;
       
  1469                     Object[] temp = new Object[n];
       
  1470                     for (int i = lo; i < hi; ++i) {
       
  1471                         Object element = elements[i];
       
  1472                         if (!c.contains(element))
       
  1473                             temp[newSize++] = element;
       
  1474                     }
       
  1475                     if (newSize != n) {
       
  1476                         Object[] newElements = new Object[len - n + newSize];
       
  1477                         System.arraycopy(elements, 0, newElements, 0, lo);
       
  1478                         System.arraycopy(temp, 0, newElements, lo, newSize);
       
  1479                         System.arraycopy(elements, hi, newElements,
       
  1480                                          lo + newSize, len - hi);
       
  1481                         size = newSize;
       
  1482                         removed = true;
       
  1483                         l.setArray(expectedArray = newElements);
       
  1484                     }
       
  1485                 }
  1310             } finally {
  1486             } finally {
  1311                 lock.unlock();
  1487                 lock.unlock();
  1312             }
  1488             }
  1313         }
  1489             return removed;
  1314 
  1490         }
  1315         @Override
  1491 
  1316         public void replaceAll(UnaryOperator<E> operator) {
  1492         public boolean retainAll(Collection<?> c) {
       
  1493             if (c == null) throw new NullPointerException();
       
  1494             boolean removed = false;
  1317             final ReentrantLock lock = l.lock;
  1495             final ReentrantLock lock = l.lock;
  1318             lock.lock();
  1496             lock.lock();
  1319             try {
  1497             try {
  1320                 checkForComodification();
  1498                 int n = size;
  1321                 l.replaceAll(operator, offset, offset + size);
  1499                 if (n > 0) {
  1322                 expectedArray = l.getArray();
  1500                     int lo = offset;
       
  1501                     int hi = offset + n;
       
  1502                     Object[] elements = expectedArray;
       
  1503                     if (l.getArray() != elements)
       
  1504                         throw new ConcurrentModificationException();
       
  1505                     int len = elements.length;
       
  1506                     if (lo < 0 || hi > len)
       
  1507                         throw new IndexOutOfBoundsException();
       
  1508                     int newSize = 0;
       
  1509                     Object[] temp = new Object[n];
       
  1510                     for (int i = lo; i < hi; ++i) {
       
  1511                         Object element = elements[i];
       
  1512                         if (c.contains(element))
       
  1513                             temp[newSize++] = element;
       
  1514                     }
       
  1515                     if (newSize != n) {
       
  1516                         Object[] newElements = new Object[len - n + newSize];
       
  1517                         System.arraycopy(elements, 0, newElements, 0, lo);
       
  1518                         System.arraycopy(temp, 0, newElements, lo, newSize);
       
  1519                         System.arraycopy(elements, hi, newElements,
       
  1520                                          lo + newSize, len - hi);
       
  1521                         size = newSize;
       
  1522                         removed = true;
       
  1523                         l.setArray(expectedArray = newElements);
       
  1524                     }
       
  1525                 }
  1323             } finally {
  1526             } finally {
  1324                 lock.unlock();
  1527                 lock.unlock();
  1325             }
  1528             }
       
  1529             return removed;
       
  1530         }
       
  1531 
       
  1532         public boolean removeIf(Predicate<? super E> filter) {
       
  1533             if (filter == null) throw new NullPointerException();
       
  1534             boolean removed = false;
       
  1535             final ReentrantLock lock = l.lock;
       
  1536             lock.lock();
       
  1537             try {
       
  1538                 int n = size;
       
  1539                 if (n > 0) {
       
  1540                     int lo = offset;
       
  1541                     int hi = offset + n;
       
  1542                     Object[] elements = expectedArray;
       
  1543                     if (l.getArray() != elements)
       
  1544                         throw new ConcurrentModificationException();
       
  1545                     int len = elements.length;
       
  1546                     if (lo < 0 || hi > len)
       
  1547                         throw new IndexOutOfBoundsException();
       
  1548                     int newSize = 0;
       
  1549                     Object[] temp = new Object[n];
       
  1550                     for (int i = lo; i < hi; ++i) {
       
  1551                         @SuppressWarnings("unchecked") E e = (E) elements[i];
       
  1552                         if (!filter.test(e))
       
  1553                             temp[newSize++] = e;
       
  1554                     }
       
  1555                     if (newSize != n) {
       
  1556                         Object[] newElements = new Object[len - n + newSize];
       
  1557                         System.arraycopy(elements, 0, newElements, 0, lo);
       
  1558                         System.arraycopy(temp, 0, newElements, lo, newSize);
       
  1559                         System.arraycopy(elements, hi, newElements,
       
  1560                                          lo + newSize, len - hi);
       
  1561                         size = newSize;
       
  1562                         removed = true;
       
  1563                         l.setArray(expectedArray = newElements);
       
  1564                     }
       
  1565                 }
       
  1566             } finally {
       
  1567                 lock.unlock();
       
  1568             }
       
  1569             return removed;
       
  1570         }
       
  1571 
       
  1572         public Spliterator<E> spliterator() {
       
  1573             int lo = offset;
       
  1574             int hi = offset + size;
       
  1575             Object[] a = expectedArray;
       
  1576             if (l.getArray() != a)
       
  1577                 throw new ConcurrentModificationException();
       
  1578             if (lo < 0 || hi > a.length)
       
  1579                 throw new IndexOutOfBoundsException();
       
  1580             return Spliterators.spliterator
       
  1581                 (a, lo, hi, Spliterator.IMMUTABLE | Spliterator.ORDERED);
  1326         }
  1582         }
  1327     }
  1583     }
  1328 
  1584 
  1329     private static class COWSubListIterator<E> implements ListIterator<E> {
  1585     private static class COWSubListIterator<E> implements ListIterator<E> {
  1330         private final ListIterator<E> it;
  1586         private final ListIterator<E> it;
  1378         public void add(E e) {
  1634         public void add(E e) {
  1379             throw new UnsupportedOperationException();
  1635             throw new UnsupportedOperationException();
  1380         }
  1636         }
  1381 
  1637 
  1382         @Override
  1638         @Override
  1383         @SuppressWarnings("unchecked")
       
  1384         public void forEachRemaining(Consumer<? super E> action) {
  1639         public void forEachRemaining(Consumer<? super E> action) {
  1385             Objects.requireNonNull(action);
  1640             Objects.requireNonNull(action);
  1386             while (nextIndex() < size) {
  1641             int s = size;
  1387                 action.accept(it.next());
  1642             ListIterator<E> i = it;
       
  1643             while (nextIndex() < s) {
       
  1644                 action.accept(i.next());
  1388             }
  1645             }
  1389         }
  1646         }
  1390     }
  1647     }
  1391 
  1648 
  1392     // Support for resetting lock while deserializing
  1649     // Support for resetting lock while deserializing
  1403                 (k.getDeclaredField("lock"));
  1660                 (k.getDeclaredField("lock"));
  1404         } catch (Exception e) {
  1661         } catch (Exception e) {
  1405             throw new Error(e);
  1662             throw new Error(e);
  1406         }
  1663         }
  1407     }
  1664     }
  1408 
       
  1409     @Override
       
  1410     @SuppressWarnings("unchecked")
       
  1411     public void forEach(Consumer<? super E> action) {
       
  1412         forEach(action, (E[]) getArray(), 0, size());
       
  1413     }
       
  1414 
       
  1415     private void forEach(Consumer<? super E> action,
       
  1416                          final E[] elements,
       
  1417                          final int from, final int to) {
       
  1418         Objects.requireNonNull(action);
       
  1419         for (int i = from; i < to; i++) {
       
  1420             action.accept(elements[i]);
       
  1421         }
       
  1422     }
       
  1423 
       
  1424     @Override
       
  1425     public void sort(Comparator<? super E> c) {
       
  1426         final ReentrantLock lock = this.lock;
       
  1427         lock.lock();
       
  1428         try {
       
  1429             sort(c, 0, size());
       
  1430         } finally {
       
  1431             lock.unlock();
       
  1432         }
       
  1433     }
       
  1434 
       
  1435     // must be called with this.lock held
       
  1436     @SuppressWarnings("unchecked")
       
  1437     private void sort(Comparator<? super E> c, final int from, final int to) {
       
  1438         final E[] elements = (E[]) getArray();
       
  1439         final E[] newElements = Arrays.copyOf(elements, elements.length);
       
  1440         // only elements [from, to) are sorted
       
  1441         Arrays.sort(newElements, from, to, c);
       
  1442         setArray(newElements);
       
  1443     }
       
  1444 
       
  1445     @Override
       
  1446     public boolean removeIf(Predicate<? super E> filter) {
       
  1447         Objects.requireNonNull(filter);
       
  1448         final ReentrantLock lock = this.lock;
       
  1449         lock.lock();
       
  1450         try {
       
  1451             return removeIf(filter, 0, size()) > 0;
       
  1452         } finally {
       
  1453             lock.unlock();
       
  1454         }
       
  1455     }
       
  1456 
       
  1457     // must be called with this.lock held
       
  1458     private int removeIf(Predicate<? super E> filter, final int from, final int to) {
       
  1459         Objects.requireNonNull(filter);
       
  1460         final ReentrantLock lock = this.lock;
       
  1461         lock.lock();
       
  1462         try {
       
  1463             @SuppressWarnings("unchecked")
       
  1464             final E[] elements = (E[]) getArray();
       
  1465 
       
  1466             // figure out which elements are to be removed
       
  1467             // any exception thrown from the filter predicate at this stage
       
  1468             // will leave the collection unmodified
       
  1469             int removeCount = 0;
       
  1470             final int range = to - from;
       
  1471             final BitSet removeSet = new BitSet(range);
       
  1472             for (int i = 0; i < range; i++) {
       
  1473                 final E element = elements[from + i];
       
  1474                 if (filter.test(element)) {
       
  1475                     // removeSet is zero-based to keep its size small
       
  1476                     removeSet.set(i);
       
  1477                     removeCount++;
       
  1478                 }
       
  1479             }
       
  1480 
       
  1481             // copy surviving elements into a new array
       
  1482             if (removeCount > 0) {
       
  1483                 final int newSize = elements.length - removeCount;
       
  1484                 final int newRange = newSize - from;
       
  1485                 @SuppressWarnings("unchecked")
       
  1486                 final E[] newElements = (E[]) new Object[newSize];
       
  1487                 // copy elements before [from, to) unmodified
       
  1488                 for (int i = 0; i < from; i++) {
       
  1489                     newElements[i] = elements[i];
       
  1490                 }
       
  1491                 // elements [from, to) are subject to removal
       
  1492                 int j = 0;
       
  1493                 for (int i = 0; (i < range) && (j < newRange); i++) {
       
  1494                     i = removeSet.nextClearBit(i);
       
  1495                     if (i >= range) {
       
  1496                         break;
       
  1497                     }
       
  1498                     newElements[from + (j++)] = elements[from + i];
       
  1499                 }
       
  1500                 // copy any remaining elements beyond [from, to)
       
  1501                 j += from;
       
  1502                 for (int i = to; (i < elements.length) && (j < newSize); i++) {
       
  1503                     newElements[j++] = elements[i];
       
  1504                 }
       
  1505                 setArray(newElements);
       
  1506             }
       
  1507 
       
  1508             return removeCount;
       
  1509         } finally {
       
  1510             lock.unlock();
       
  1511         }
       
  1512     }
       
  1513 
       
  1514     @Override
       
  1515     public void replaceAll(UnaryOperator<E> operator) {
       
  1516         Objects.requireNonNull(operator);
       
  1517         final ReentrantLock lock = this.lock;
       
  1518         lock.lock();
       
  1519         try {
       
  1520             replaceAll(operator, 0, size());
       
  1521         } finally {
       
  1522             lock.unlock();
       
  1523         }
       
  1524     }
       
  1525 
       
  1526     // must be called with this.lock held
       
  1527     @SuppressWarnings("unchecked")
       
  1528     private void replaceAll(UnaryOperator<E> operator, final int from, final int to) {
       
  1529         final E[] elements = (E[]) getArray();
       
  1530         final E[] newElements = (E[]) new Object[elements.length];
       
  1531         for (int i = 0; i < from; i++) {
       
  1532             newElements[i] = elements[i];
       
  1533         }
       
  1534         // the operator is only applied to elements [from, to)
       
  1535         for (int i = from; i < to; i++) {
       
  1536             newElements[i] = operator.apply(elements[i]);
       
  1537         }
       
  1538         for (int i = to; i < elements.length; i++) {
       
  1539             newElements[i] = elements[i];
       
  1540         }
       
  1541         setArray(newElements);
       
  1542     }
       
  1543 }
  1665 }