1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Written by Doug Lea with assistance from members of JCP JSR-166
3bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * Expert Group and released to the public domain, as explained at
4a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson * http://creativecommons.org/publicdomain/zero/1.0/
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage java.util.concurrent;
88eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilsonimport java.util.*;
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// BEGIN android-note
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// removed link to collections framework docs
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project// END android-note
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
15bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * A {@link java.util.Set} that uses an internal {@link CopyOnWriteArrayList}
16bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * for all of its operations.  Thus, it shares the same basic properties:
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <ul>
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *  <li>It is best suited for applications in which set sizes generally
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       stay small, read-only operations
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       vastly outnumber mutative operations, and you need
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *       to prevent interference among threads during traversal.
22bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *  <li>It is thread-safe.
2391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle *  <li>Mutative operations ({@code add}, {@code set}, {@code remove}, etc.)
24bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *      are expensive since they usually entail copying the entire underlying
25bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *      array.
2691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle *  <li>Iterators do not support the mutative {@code remove} operation.
27bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *  <li>Traversal via iterators is fast and cannot encounter
28adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *      interference from other threads. Iterators rely on
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *      unchanging snapshots of the array at the time the iterators were
30bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *      constructed.
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </ul>
32bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
3391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle * <p><b>Sample Usage.</b> The following code sketch uses a
34bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * copy-on-write set to maintain a set of Handler objects that
35bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * perform some action upon state updates.
36bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson *
378eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *  <pre> {@code
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class Handler { void handle(); ... }
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * class X {
418eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *   private final CopyOnWriteArraySet<Handler> handlers
428eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *     = new CopyOnWriteArraySet<Handler>();
438eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *   public void addHandler(Handler h) { handlers.add(h); }
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
458eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *   private long internalState;
468eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *   private synchronized void changeState() { internalState = ...; }
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
488eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *   public void update() {
498eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *     changeState();
508eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *     for (Handler handler : handlers)
5191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle *       handler.handle();
528eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson *   }
538eb35c835be1345d3873a82cc9e42f944d698afdJesse Wilson * }}</pre>
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
55bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson * @see CopyOnWriteArrayList
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @since 1.5
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @author Doug Lea
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * @param <E> the type of elements held in this collection
59adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class CopyOnWriteArraySet<E> extends AbstractSet<E>
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        implements java.io.Serializable {
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private static final long serialVersionUID = 5457747651344034263L;
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private final CopyOnWriteArrayList<E> al;
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates an empty set.
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public CopyOnWriteArraySet() {
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        al = new CopyOnWriteArrayList<E>();
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Creates a set containing all of the elements of the specified
75bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * collection.
76bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
77bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param c the collection of elements to initially contain
78bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if the specified collection is null
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public CopyOnWriteArraySet(Collection<? extends E> c) {
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        al = new CopyOnWriteArrayList<E>();
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        al.addAllAbsent(c);
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
85bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
86bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns the number of elements in this set.
87bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
88bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return the number of elements in this set
89bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
90bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public int size() {
91bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.size();
92bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
93bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
94bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
9591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * Returns {@code true} if this set contains no elements.
96bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
9791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return {@code true} if this set contains no elements
98bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
99bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean isEmpty() {
100bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.isEmpty();
101bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
102bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
103bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
10491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * Returns {@code true} if this set contains the specified element.
10591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * More formally, returns {@code true} if and only if this set
10691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * contains an element {@code e} such that
107bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>.
108bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
109bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param o element whose presence in this set is to be tested
11091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return {@code true} if this set contains the specified element
111bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
112bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean contains(Object o) {
113bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.contains(o);
114bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
115bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
116bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
117bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns an array containing all of the elements in this set.
118bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * If this set makes any guarantees as to what order its elements
119bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * are returned by its iterator, this method must return the
120bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * elements in the same order.
121bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
122bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>The returned array will be "safe" in that no references to it
123bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * are maintained by this set.  (In other words, this method must
124bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * allocate a new array even if this set is backed by an array).
125bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The caller is thus free to modify the returned array.
126bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
127bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>This method acts as bridge between array-based and collection-based
128bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * APIs.
129bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
130bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return an array containing all the elements in this set
131bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
132bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public Object[] toArray() {
133bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.toArray();
134bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
135bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
136bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
137bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns an array containing all of the elements in this set; the
138bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * runtime type of the returned array is that of the specified array.
139bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * If the set fits in the specified array, it is returned therein.
140bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Otherwise, a new array is allocated with the runtime type of the
141bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * specified array and the size of this set.
142bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
143bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>If this set fits in the specified array with room to spare
144bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * (i.e., the array has more elements than this set), the element in
145bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the array immediately following the end of the set is set to
14691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * {@code null}.  (This is useful in determining the length of this
147bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * set <i>only</i> if the caller knows that this set does not contain
148bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * any null elements.)
149bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
150bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>If this set makes any guarantees as to what order its elements
151bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * are returned by its iterator, this method must return the elements
152bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * in the same order.
153bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
154bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>Like the {@link #toArray()} method, this method acts as bridge between
155bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * array-based and collection-based APIs.  Further, this method allows
156bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * precise control over the runtime type of the output array, and may,
157bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * under certain circumstances, be used to save allocation costs.
158bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
15991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * <p>Suppose {@code x} is a set known to contain only strings.
160bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The following code can be used to dump the set into a newly allocated
16191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * array of {@code String}:
162bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
163a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson     *  <pre> {@code String[] y = x.toArray(new String[0]);}</pre>
164bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
16591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * Note that {@code toArray(new Object[0])} is identical in function to
16691770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * {@code toArray()}.
167bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
168bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param a the array into which the elements of this set are to be
169bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        stored, if it is big enough; otherwise, a new array of the same
170bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *        runtime type is allocated for this purpose.
171bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return an array containing all the elements in this set
172bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ArrayStoreException if the runtime type of the specified array
173bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         is not a supertype of the runtime type of every element in this
174bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         set
175bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if the specified array is null
176bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
177bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public <T> T[] toArray(T[] a) {
178bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.toArray(a);
179bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
180bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
181bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
182bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Removes all of the elements from this set.
183bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * The set will be empty after this call returns.
184bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
185bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public void clear() {
186bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        al.clear();
187bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
188adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
189bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
190bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Removes the specified element from this set if it is present.
19191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * More formally, removes an element {@code e} such that
192bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <tt>(o==null&nbsp;?&nbsp;e==null&nbsp;:&nbsp;o.equals(e))</tt>,
19391770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * if this set contains such an element.  Returns {@code true} if
194bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * this set contained the element (or equivalently, if this set
195bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * changed as a result of the call).  (This set will not contain the
196bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * element once the call returns.)
197bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
198bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param o object to be removed from this set, if present
19991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return {@code true} if this set contained the specified element
200bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
201bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean remove(Object o) {
202bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.remove(o);
203bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
205bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
206bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Adds the specified element to this set if it is not already present.
20791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * More formally, adds the specified element {@code e} to this set if
20891770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * the set contains no element {@code e2} such that
209bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <tt>(e==null&nbsp;?&nbsp;e2==null&nbsp;:&nbsp;e.equals(e2))</tt>.
210bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * If this set already contains the element, the call leaves the set
21191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * unchanged and returns {@code false}.
212bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
213bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param e element to be added to this set
21491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return {@code true} if this set did not already contain the specified
215bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         element
216bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
217bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean add(E e) {
218bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.addIfAbsent(e);
219bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
220bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
221bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
22291770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * Returns {@code true} if this set contains all of the elements of the
223bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * specified collection.  If the specified collection is also a set, this
22491770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * method returns {@code true} if it is a <i>subset</i> of this set.
225bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
226bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param  c collection to be checked for containment in this set
22791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return {@code true} if this set contains all of the elements of the
228bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         specified collection
229bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if the specified collection is null
230bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @see #contains(Object)
231bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
232bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean containsAll(Collection<?> c) {
233bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.containsAll(c);
234bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
235bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
236bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
237bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Adds all of the elements in the specified collection to this set if
238bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * they're not already present.  If the specified collection is also a
23991770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * set, the {@code addAll} operation effectively modifies this set so
240bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * that its value is the <i>union</i> of the two sets.  The behavior of
241bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * this operation is undefined if the specified collection is modified
242bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * while the operation is in progress.
243bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
244bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param  c collection containing elements to be added to this set
24591770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return {@code true} if this set changed as a result of the call
246bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if the specified collection is null
247bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @see #add(Object)
248bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
249bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean addAll(Collection<? extends E> c) {
250bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.addAllAbsent(c) > 0;
251bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
252bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
253bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
254bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Removes from this set all of its elements that are contained in the
255bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * specified collection.  If the specified collection is also a set,
256bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * this operation effectively modifies this set so that its value is the
257bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <i>asymmetric set difference</i> of the two sets.
258bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
259bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param  c collection containing elements to be removed from this set
26091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return {@code true} if this set changed as a result of the call
261bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ClassCastException if the class of an element of this set
262bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         is incompatible with the specified collection (optional)
263bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if this set contains a null element and the
264bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         specified collection does not permit null elements (optional),
265bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         or if the specified collection is null
266bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @see #remove(Object)
267bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
268bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean removeAll(Collection<?> c) {
269bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.removeAll(c);
270bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
271bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
272bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
273bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Retains only the elements in this set that are contained in the
274bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * specified collection.  In other words, removes from this set all of
275bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * its elements that are not contained in the specified collection.  If
276bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the specified collection is also a set, this operation effectively
277bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * modifies this set so that its value is the <i>intersection</i> of the
278bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * two sets.
279bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
280bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param  c collection containing elements to be retained in this set
28191770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * @return {@code true} if this set changed as a result of the call
282bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws ClassCastException if the class of an element of this set
283bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         is incompatible with the specified collection (optional)
284bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @throws NullPointerException if this set contains a null element and the
285bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         specified collection does not permit null elements (optional),
286bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *         or if the specified collection is null
287bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @see #remove(Object)
288bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
289bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean retainAll(Collection<?> c) {
290bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.retainAll(c);
291bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
292bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
293bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
294bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns an iterator over the elements contained in this set
295bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * in the order in which these elements were added.
296bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
297bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * <p>The returned iterator provides a snapshot of the state of the set
298bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * when the iterator was constructed. No synchronization is needed while
299bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * traversing the iterator. The iterator does <em>NOT</em> support the
30091770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * {@code remove} method.
301bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
302bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return an iterator over the elements in this set
303bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
304bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public Iterator<E> iterator() {
305bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return al.iterator();
306bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
307bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
308bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
309bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Compares the specified object with this set for equality.
310bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * Returns {@code true} if the specified object is the same object
311bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * as this object, or if it is also a {@link Set} and the elements
312bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * returned by an {@linkplain List#iterator() iterator} over the
313bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * specified set are the same as the elements returned by an
314bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * iterator over this set.  More formally, the two iterators are
315bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * considered to return the same elements if they return the same
316bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * number of elements and for every element {@code e1} returned by
317bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * the iterator over the specified set, there is an element
318bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * {@code e2} returned by the iterator over this set such that
319bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * {@code (e1==null ? e2==null : e1.equals(e2))}.
320bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     *
321bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @param o object to be compared for equality with this set
322bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     * @return {@code true} if the specified object is equal to this set
323bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
324bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    public boolean equals(Object o) {
325bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (o == this)
326bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            return true;
327bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        if (!(o instanceof Set))
328bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            return false;
329bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        Set<?> set = (Set<?>)(o);
330bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        Iterator<?> it = set.iterator();
331bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
332bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        // Uses O(n^2) algorithm that is only appropriate
333bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        // for small sets, which CopyOnWriteArraySets should be.
334bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
335bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        //  Use a single snapshot of underlying array
336bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        Object[] elements = al.getArray();
337bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        int len = elements.length;
338bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        // Mark matched elements to avoid re-checking
339bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        boolean[] matched = new boolean[len];
340bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        int k = 0;
341bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        outer: while (it.hasNext()) {
342bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            if (++k > len)
343bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                return false;
344bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            Object x = it.next();
345bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            for (int i = 0; i < len; ++i) {
346bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                if (!matched[i] && eq(x, elements[i])) {
347bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    matched[i] = true;
348bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                    continue outer;
349bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson                }
350bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            }
351bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson            return false;
352bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        }
353bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson        return k == len;
354bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
355bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson
356bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    /**
35791770798d8b9280d48d30df2ed7f63b3ed9b036fCalin Juravle     * Tests for equality, coping with nulls.
358bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson     */
359bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    private static boolean eq(Object o1, Object o2) {
360a807b4d808d2591894daf13aab179b2e9c46a2f5Jesse Wilson        return (o1 == null) ? o2 == null : o1.equals(o2);
361bba8d1acd6dfff06c94d761c67a30154ca5ca5dfJesse Wilson    }
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
363