ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/AbstractCollection.java
Revision: 1.12
Committed: Sun May 18 23:47:55 2008 UTC (16 years ago) by jsr166
Branch: MAIN
Changes since 1.11: +102 -102 lines
Log Message:
Sync with OpenJDK; untabify

File Contents

# User Rev Content
1 dl 1.1 /*
2 jsr166 1.11 * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
3     * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 dl 1.1 *
5 jsr166 1.11 * 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
7     * published by the Free Software Foundation. Sun designates this
8     * particular file as subject to the "Classpath" exception as provided
9     * by Sun in the LICENSE file that accompanied this code.
10     *
11     * This code is distributed in the hope that it will be useful, but WITHOUT
12     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13     * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14     * version 2 for more details (a copy is included in the LICENSE file that
15     * accompanied this code).
16     *
17     * You should have received a copy of the GNU General Public License version
18     * 2 along with this work; if not, write to the Free Software Foundation,
19     * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20     *
21     * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22     * CA 95054 USA or visit www.sun.com if you need additional information or
23     * have any questions.
24 dl 1.1 */
25    
26     package java.util;
27    
28     /**
29     * This class provides a skeletal implementation of the <tt>Collection</tt>
30     * interface, to minimize the effort required to implement this interface. <p>
31     *
32     * To implement an unmodifiable collection, the programmer needs only to
33     * extend this class and provide implementations for the <tt>iterator</tt> and
34     * <tt>size</tt> methods. (The iterator returned by the <tt>iterator</tt>
35     * method must implement <tt>hasNext</tt> and <tt>next</tt>.)<p>
36     *
37     * To implement a modifiable collection, the programmer must additionally
38     * override this class's <tt>add</tt> method (which otherwise throws an
39     * <tt>UnsupportedOperationException</tt>), and the iterator returned by the
40     * <tt>iterator</tt> method must additionally implement its <tt>remove</tt>
41     * method.<p>
42     *
43     * The programmer should generally provide a void (no argument) and
44     * <tt>Collection</tt> constructor, as per the recommendation in the
45     * <tt>Collection</tt> interface specification.<p>
46     *
47 jsr166 1.9 * The documentation for each non-abstract method in this class describes its
48 dl 1.1 * implementation in detail. Each of these methods may be overridden if
49     * the collection being implemented admits a more efficient implementation.<p>
50     *
51     * This class is a member of the
52 jsr166 1.8 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
53 dl 1.1 * Java Collections Framework</a>.
54     *
55     * @author Josh Bloch
56     * @author Neal Gafter
57 jsr166 1.6 * @version %I%, %G%
58 dl 1.1 * @see Collection
59     * @since 1.2
60     */
61    
62     public abstract class AbstractCollection<E> implements Collection<E> {
63     /**
64     * Sole constructor. (For invocation by subclass constructors, typically
65     * implicit.)
66     */
67     protected AbstractCollection() {
68     }
69    
70     // Query Operations
71    
72     /**
73     * Returns an iterator over the elements contained in this collection.
74     *
75     * @return an iterator over the elements contained in this collection
76     */
77     public abstract Iterator<E> iterator();
78    
79     public abstract int size();
80    
81     /**
82     * {@inheritDoc}
83     *
84     * <p>This implementation returns <tt>size() == 0</tt>.
85     */
86     public boolean isEmpty() {
87 jsr166 1.12 return size() == 0;
88 dl 1.1 }
89    
90     /**
91     * {@inheritDoc}
92     *
93     * <p>This implementation iterates over the elements in the collection,
94     * checking each element in turn for equality with the specified element.
95     *
96     * @throws ClassCastException {@inheritDoc}
97     * @throws NullPointerException {@inheritDoc}
98     */
99     public boolean contains(Object o) {
100 jsr166 1.12 Iterator<E> e = iterator();
101     if (o==null) {
102     while (e.hasNext())
103     if (e.next()==null)
104     return true;
105     } else {
106     while (e.hasNext())
107     if (o.equals(e.next()))
108     return true;
109     }
110     return false;
111 dl 1.1 }
112    
113     /**
114     * {@inheritDoc}
115     *
116 jsr166 1.9 * <p>This implementation returns an array containing all the elements
117     * returned by this collection's iterator, in the same order, stored in
118     * consecutive elements of the array, starting with index {@code 0}.
119     * The length of the returned array is equal to the number of elements
120     * returned by the iterator, even if the size of this collection changes
121     * during iteration, as might happen if the collection permits
122     * concurrent modification during iteration. The {@code size} method is
123     * called only as an optimization hint; the correct result is returned
124     * even if the iterator returns a different number of elements.
125     *
126     * <p>This method is equivalent to:
127     *
128     * <pre> {@code
129     * List<E> list = new ArrayList<E>(size());
130     * for (E e : this)
131     * list.add(e);
132     * return list.toArray();
133     * }</pre>
134 dl 1.1 */
135     public Object[] toArray() {
136     // Estimate size of array; be prepared to see more or fewer elements
137 jsr166 1.12 Object[] r = new Object[size()];
138 jsr166 1.3 Iterator<E> it = iterator();
139 jsr166 1.12 for (int i = 0; i < r.length; i++) {
140     if (! it.hasNext()) // fewer elements than expected
141     return Arrays.copyOf(r, i);
142     r[i] = it.next();
143     }
144     return it.hasNext() ? finishToArray(r, it) : r;
145 dl 1.1 }
146    
147     /**
148     * {@inheritDoc}
149     *
150 jsr166 1.9 * <p>This implementation returns an array containing all the elements
151     * returned by this collection's iterator in the same order, stored in
152     * consecutive elements of the array, starting with index {@code 0}.
153     * If the number of elements returned by the iterator is too large to
154     * fit into the specified array, then the elements are returned in a
155     * newly allocated array with length equal to the number of elements
156     * returned by the iterator, even if the size of this collection
157     * changes during iteration, as might happen if the collection permits
158     * concurrent modification during iteration. The {@code size} method is
159     * called only as an optimization hint; the correct result is returned
160     * even if the iterator returns a different number of elements.
161     *
162     * <p>This method is equivalent to:
163     *
164     * <pre> {@code
165     * List<E> list = new ArrayList<E>(size());
166     * for (E e : this)
167     * list.add(e);
168     * return list.toArray(a);
169     * }</pre>
170 dl 1.1 *
171     * @throws ArrayStoreException {@inheritDoc}
172     * @throws NullPointerException {@inheritDoc}
173     */
174     public <T> T[] toArray(T[] a) {
175     // Estimate size of array; be prepared to see more or fewer elements
176     int size = size();
177 jsr166 1.3 T[] r = a.length >= size ? a :
178 dl 1.1 (T[])java.lang.reflect.Array
179     .newInstance(a.getClass().getComponentType(), size);
180 jsr166 1.3 Iterator<E> it = iterator();
181 jsr166 1.9
182 jsr166 1.12 for (int i = 0; i < r.length; i++) {
183     if (! it.hasNext()) { // fewer elements than expected
184     if (a != r)
185     return Arrays.copyOf(r, i);
186     r[i] = null; // null-terminate
187     return r;
188     }
189     r[i] = (T)it.next();
190     }
191     return it.hasNext() ? finishToArray(r, it) : r;
192 dl 1.1 }
193    
194     /**
195 jsr166 1.9 * Reallocates the array being used within toArray when the iterator
196     * returned more elements than expected, and finishes filling it from
197     * the iterator.
198     *
199     * @param r the array, replete with previously stored elements
200     * @param it the in-progress iterator over this collection
201 jsr166 1.3 * @return array containing the elements in the given array, plus any
202     * further elements returned by the iterator, trimmed to size
203 dl 1.1 */
204 jsr166 1.9 private static <T> T[] finishToArray(T[] r, Iterator<?> it) {
205 jsr166 1.12 int i = r.length;
206 jsr166 1.2 while (it.hasNext()) {
207 dl 1.1 int cap = r.length;
208 jsr166 1.9 if (i == cap) {
209 dl 1.4 int newCap = ((cap / 2) + 1) * 3;
210     if (newCap <= cap) { // integer overflow
211 jsr166 1.12 if (cap == Integer.MAX_VALUE)
212     throw new OutOfMemoryError
213     ("Required array size too large");
214     newCap = Integer.MAX_VALUE;
215     }
216     r = Arrays.copyOf(r, newCap);
217     }
218     r[i++] = (T)it.next();
219 jsr166 1.7 }
220 dl 1.1 // trim if overallocated
221 jsr166 1.9 return (i == r.length) ? r : Arrays.copyOf(r, i);
222 dl 1.1 }
223    
224     // Modification Operations
225    
226     /**
227     * {@inheritDoc}
228     *
229     * <p>This implementation always throws an
230     * <tt>UnsupportedOperationException</tt>.
231     *
232     * @throws UnsupportedOperationException {@inheritDoc}
233     * @throws ClassCastException {@inheritDoc}
234     * @throws NullPointerException {@inheritDoc}
235     * @throws IllegalArgumentException {@inheritDoc}
236     * @throws IllegalStateException {@inheritDoc}
237     */
238     public boolean add(E e) {
239 jsr166 1.12 throw new UnsupportedOperationException();
240 dl 1.1 }
241    
242     /**
243     * {@inheritDoc}
244     *
245     * <p>This implementation iterates over the collection looking for the
246     * specified element. If it finds the element, it removes the element
247     * from the collection using the iterator's remove method.
248     *
249     * <p>Note that this implementation throws an
250     * <tt>UnsupportedOperationException</tt> if the iterator returned by this
251     * collection's iterator method does not implement the <tt>remove</tt>
252     * method and this collection contains the specified object.
253     *
254     * @throws UnsupportedOperationException {@inheritDoc}
255     * @throws ClassCastException {@inheritDoc}
256     * @throws NullPointerException {@inheritDoc}
257     */
258     public boolean remove(Object o) {
259 jsr166 1.12 Iterator<E> e = iterator();
260     if (o==null) {
261     while (e.hasNext()) {
262     if (e.next()==null) {
263     e.remove();
264     return true;
265     }
266     }
267     } else {
268     while (e.hasNext()) {
269     if (o.equals(e.next())) {
270     e.remove();
271     return true;
272     }
273     }
274     }
275     return false;
276 dl 1.1 }
277    
278    
279     // Bulk Operations
280    
281     /**
282     * {@inheritDoc}
283     *
284     * <p>This implementation iterates over the specified collection,
285     * checking each element returned by the iterator in turn to see
286     * if it's contained in this collection. If all elements are so
287     * contained <tt>true</tt> is returned, otherwise <tt>false</tt>.
288     *
289     * @throws ClassCastException {@inheritDoc}
290     * @throws NullPointerException {@inheritDoc}
291     * @see #contains(Object)
292     */
293     public boolean containsAll(Collection<?> c) {
294 jsr166 1.12 Iterator<?> e = c.iterator();
295     while (e.hasNext())
296     if (!contains(e.next()))
297     return false;
298     return true;
299 dl 1.1 }
300    
301     /**
302     * {@inheritDoc}
303     *
304     * <p>This implementation iterates over the specified collection, and adds
305     * each object returned by the iterator to this collection, in turn.
306     *
307     * <p>Note that this implementation will throw an
308     * <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is
309     * overridden (assuming the specified collection is non-empty).
310     *
311     * @throws UnsupportedOperationException {@inheritDoc}
312     * @throws ClassCastException {@inheritDoc}
313     * @throws NullPointerException {@inheritDoc}
314     * @throws IllegalArgumentException {@inheritDoc}
315     * @throws IllegalStateException {@inheritDoc}
316     *
317     * @see #add(Object)
318     */
319     public boolean addAll(Collection<? extends E> c) {
320 jsr166 1.12 boolean modified = false;
321     Iterator<? extends E> e = c.iterator();
322     while (e.hasNext()) {
323     if (add(e.next()))
324     modified = true;
325     }
326     return modified;
327 dl 1.1 }
328    
329     /**
330     * {@inheritDoc}
331     *
332     * <p>This implementation iterates over this collection, checking each
333     * element returned by the iterator in turn to see if it's contained
334     * in the specified collection. If it's so contained, it's removed from
335     * this collection with the iterator's <tt>remove</tt> method.
336     *
337     * <p>Note that this implementation will throw an
338     * <tt>UnsupportedOperationException</tt> if the iterator returned by the
339     * <tt>iterator</tt> method does not implement the <tt>remove</tt> method
340     * and this collection contains one or more elements in common with the
341     * specified collection.
342     *
343     * @throws UnsupportedOperationException {@inheritDoc}
344     * @throws ClassCastException {@inheritDoc}
345     * @throws NullPointerException {@inheritDoc}
346     *
347     * @see #remove(Object)
348     * @see #contains(Object)
349     */
350     public boolean removeAll(Collection<?> c) {
351 jsr166 1.12 boolean modified = false;
352     Iterator<?> e = iterator();
353     while (e.hasNext()) {
354     if (c.contains(e.next())) {
355     e.remove();
356     modified = true;
357     }
358     }
359     return modified;
360 dl 1.1 }
361    
362     /**
363     * {@inheritDoc}
364     *
365     * <p>This implementation iterates over this collection, checking each
366     * element returned by the iterator in turn to see if it's contained
367     * in the specified collection. If it's not so contained, it's removed
368     * from this collection with the iterator's <tt>remove</tt> method.
369     *
370     * <p>Note that this implementation will throw an
371     * <tt>UnsupportedOperationException</tt> if the iterator returned by the
372     * <tt>iterator</tt> method does not implement the <tt>remove</tt> method
373     * and this collection contains one or more elements not present in the
374     * specified collection.
375     *
376     * @throws UnsupportedOperationException {@inheritDoc}
377     * @throws ClassCastException {@inheritDoc}
378     * @throws NullPointerException {@inheritDoc}
379     *
380     * @see #remove(Object)
381     * @see #contains(Object)
382     */
383     public boolean retainAll(Collection<?> c) {
384 jsr166 1.12 boolean modified = false;
385     Iterator<E> e = iterator();
386     while (e.hasNext()) {
387     if (!c.contains(e.next())) {
388     e.remove();
389     modified = true;
390     }
391     }
392     return modified;
393 dl 1.1 }
394    
395     /**
396     * {@inheritDoc}
397     *
398     * <p>This implementation iterates over this collection, removing each
399     * element using the <tt>Iterator.remove</tt> operation. Most
400     * implementations will probably choose to override this method for
401     * efficiency.
402     *
403     * <p>Note that this implementation will throw an
404     * <tt>UnsupportedOperationException</tt> if the iterator returned by this
405     * collection's <tt>iterator</tt> method does not implement the
406     * <tt>remove</tt> method and this collection is non-empty.
407     *
408     * @throws UnsupportedOperationException {@inheritDoc}
409     */
410     public void clear() {
411 jsr166 1.12 Iterator<E> e = iterator();
412     while (e.hasNext()) {
413     e.next();
414     e.remove();
415     }
416 dl 1.1 }
417    
418    
419     // String conversion
420    
421     /**
422     * Returns a string representation of this collection. The string
423     * representation consists of a list of the collection's elements in the
424     * order they are returned by its iterator, enclosed in square brackets
425     * (<tt>"[]"</tt>). Adjacent elements are separated by the characters
426     * <tt>", "</tt> (comma and space). Elements are converted to strings as
427     * by {@link String#valueOf(Object)}.
428     *
429     * @return a string representation of this collection
430     */
431     public String toString() {
432     Iterator<E> i = iterator();
433 jsr166 1.12 if (! i.hasNext())
434     return "[]";
435 dl 1.1
436 jsr166 1.12 StringBuilder sb = new StringBuilder();
437     sb.append('[');
438     for (;;) {
439     E e = i.next();
440     sb.append(e == this ? "(this Collection)" : e);
441     if (! i.hasNext())
442     return sb.append(']').toString();
443     sb.append(", ");
444     }
445 dl 1.1 }
446    
447     }