ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/AbstractCollection.java
Revision: 1.3
Committed: Sat Nov 26 20:59:57 2005 UTC (18 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.2: +12 -10 lines
Log Message:
small fixups

File Contents

# User Rev Content
1 dl 1.1 /*
2 jsr166 1.3 * %W% %E%
3 dl 1.1 *
4     * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
5     * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6     */
7    
8     package java.util;
9    
10     /**
11     * This class provides a skeletal implementation of the <tt>Collection</tt>
12     * interface, to minimize the effort required to implement this interface. <p>
13     *
14     * To implement an unmodifiable collection, the programmer needs only to
15     * extend this class and provide implementations for the <tt>iterator</tt> and
16     * <tt>size</tt> methods. (The iterator returned by the <tt>iterator</tt>
17     * method must implement <tt>hasNext</tt> and <tt>next</tt>.)<p>
18     *
19     * To implement a modifiable collection, the programmer must additionally
20     * override this class's <tt>add</tt> method (which otherwise throws an
21     * <tt>UnsupportedOperationException</tt>), and the iterator returned by the
22     * <tt>iterator</tt> method must additionally implement its <tt>remove</tt>
23     * method.<p>
24     *
25     * The programmer should generally provide a void (no argument) and
26     * <tt>Collection</tt> constructor, as per the recommendation in the
27     * <tt>Collection</tt> interface specification.<p>
28     *
29     * The documentation for each non-abstract methods in this class describes its
30     * implementation in detail. Each of these methods may be overridden if
31     * the collection being implemented admits a more efficient implementation.<p>
32     *
33     * This class is a member of the
34     * <a href="{@docRoot}/../guide/collections/index.html">
35     * Java Collections Framework</a>.
36     *
37     * @author Josh Bloch
38     * @author Neal Gafter
39     * @version 1.24, 01/18/03
40     * @see Collection
41     * @since 1.2
42     */
43    
44     public abstract class AbstractCollection<E> implements Collection<E> {
45     /**
46     * Sole constructor. (For invocation by subclass constructors, typically
47     * implicit.)
48     */
49     protected AbstractCollection() {
50     }
51    
52     // Query Operations
53    
54     /**
55     * Returns an iterator over the elements contained in this collection.
56     *
57     * @return an iterator over the elements contained in this collection
58     */
59     public abstract Iterator<E> iterator();
60    
61     public abstract int size();
62    
63     /**
64     * {@inheritDoc}
65     *
66     * <p>This implementation returns <tt>size() == 0</tt>.
67     */
68     public boolean isEmpty() {
69     return size() == 0;
70     }
71    
72     /**
73     * {@inheritDoc}
74     *
75     * <p>This implementation iterates over the elements in the collection,
76     * checking each element in turn for equality with the specified element.
77     *
78     * @throws ClassCastException {@inheritDoc}
79     * @throws NullPointerException {@inheritDoc}
80     */
81     public boolean contains(Object o) {
82     Iterator<E> e = iterator();
83     if (o==null) {
84     while (e.hasNext())
85     if (e.next()==null)
86     return true;
87     } else {
88     while (e.hasNext())
89     if (o.equals(e.next()))
90     return true;
91     }
92     return false;
93     }
94    
95     /**
96     * {@inheritDoc}
97     *
98     * <p>This implementation allocates the array to be returned, and iterates
99     * over the elements in the collection, storing each object reference in
100     * the next consecutive element of the array, starting with element 0.
101     */
102     public Object[] toArray() {
103     // Estimate size of array; be prepared to see more or fewer elements
104     Object[] r = new Object[size()];
105     int i = 0;
106 jsr166 1.3 Iterator<E> it = iterator();
107 jsr166 1.2 while (i < r.length && it.hasNext())
108 dl 1.1 r[i++] = it.next();
109     // Trim if overallocated; expand if underallocated
110     if (i < r.length || it.hasNext())
111     return resizeAndFinishToArray(r, i, it);
112     return r;
113     }
114    
115     /**
116     * {@inheritDoc}
117     *
118     * <p>This implementation checks if the array is large enough to contain the
119     * collection; if not, it allocates a new array of the correct size and
120     * type (using reflection). Then, it iterates over the collection,
121     * storing each object reference in the next consecutive element of the
122     * array, starting with element 0. If the array is larger than the
123     * collection, a <tt>null</tt> is stored in the first location after the
124     * end of the collection.
125     *
126     * @throws ArrayStoreException {@inheritDoc}
127     * @throws NullPointerException {@inheritDoc}
128     */
129     public <T> T[] toArray(T[] a) {
130     // Estimate size of array; be prepared to see more or fewer elements
131     int size = size();
132 jsr166 1.3 T[] r = a.length >= size ? a :
133 dl 1.1 (T[])java.lang.reflect.Array
134     .newInstance(a.getClass().getComponentType(), size);
135     int i = 0;
136 jsr166 1.3 Iterator<E> it = iterator();
137 jsr166 1.2 while (i < r.length && it.hasNext())
138 dl 1.1 r[i++] = (T)it.next();
139     // Trim if overallocated; expand if underallocated
140     if (it.hasNext() || (r != a && i < r.length))
141     return resizeAndFinishToArray(r, i, it);
142 jsr166 1.2 if (i < r.length)
143 dl 1.1 r[i] = null; // null-terminate if provided array is too big
144     return r;
145     }
146    
147     /**
148 jsr166 1.3 * Reallocates the array being used within toArray that has a
149     * different number of elements than expected, and finishes
150     * filling it from the given iterator, if necessary.
151     *
152 dl 1.1 * @param r the array
153     * @param i the next array index to fill
154     * @param it the in-progress iterator over the collection
155 jsr166 1.3 * @return array containing the elements in the given array, plus any
156     * further elements returned by the iterator, trimmed to size
157 dl 1.1 */
158 jsr166 1.3 private static <T> T[] resizeAndFinishToArray(T[] r, int i, Iterator<?> it) {
159 jsr166 1.2 while (it.hasNext()) {
160 dl 1.1 int cap = r.length;
161     if (i < cap)
162     r[i++] = (T)it.next();
163     else if (cap < Integer.MAX_VALUE) { // expand
164     int newCap = (cap * 3) / 2 + 1;
165     if (newCap <= cap) // integer overflow
166     newCap = Integer.MAX_VALUE;
167     r = Arrays.copyOf(r, newCap);
168     } else // can't expand
169     throw new OutOfMemoryError("Required array size too large");
170     }
171     // trim if overallocated
172 jsr166 1.3 return i == r.length ? r : Arrays.copyOf(r, i);
173 dl 1.1 }
174    
175     // Modification Operations
176    
177     /**
178     * {@inheritDoc}
179     *
180     * <p>This implementation always throws an
181     * <tt>UnsupportedOperationException</tt>.
182     *
183     * @throws UnsupportedOperationException {@inheritDoc}
184     * @throws ClassCastException {@inheritDoc}
185     * @throws NullPointerException {@inheritDoc}
186     * @throws IllegalArgumentException {@inheritDoc}
187     * @throws IllegalStateException {@inheritDoc}
188     */
189     public boolean add(E e) {
190     throw new UnsupportedOperationException();
191     }
192    
193     /**
194     * {@inheritDoc}
195     *
196     * <p>This implementation iterates over the collection looking for the
197     * specified element. If it finds the element, it removes the element
198     * from the collection using the iterator's remove method.
199     *
200     * <p>Note that this implementation throws an
201     * <tt>UnsupportedOperationException</tt> if the iterator returned by this
202     * collection's iterator method does not implement the <tt>remove</tt>
203     * method and this collection contains the specified object.
204     *
205     * @throws UnsupportedOperationException {@inheritDoc}
206     * @throws ClassCastException {@inheritDoc}
207     * @throws NullPointerException {@inheritDoc}
208     */
209     public boolean remove(Object o) {
210     Iterator<E> e = iterator();
211     if (o==null) {
212     while (e.hasNext()) {
213     if (e.next()==null) {
214     e.remove();
215     return true;
216     }
217     }
218     } else {
219     while (e.hasNext()) {
220     if (o.equals(e.next())) {
221     e.remove();
222     return true;
223     }
224     }
225     }
226     return false;
227     }
228    
229    
230     // Bulk Operations
231    
232     /**
233     * {@inheritDoc}
234     *
235     * <p>This implementation iterates over the specified collection,
236     * checking each element returned by the iterator in turn to see
237     * if it's contained in this collection. If all elements are so
238     * contained <tt>true</tt> is returned, otherwise <tt>false</tt>.
239     *
240     * @throws ClassCastException {@inheritDoc}
241     * @throws NullPointerException {@inheritDoc}
242     * @see #contains(Object)
243     */
244     public boolean containsAll(Collection<?> c) {
245     Iterator<?> e = c.iterator();
246     while (e.hasNext())
247     if (!contains(e.next()))
248     return false;
249     return true;
250     }
251    
252     /**
253     * {@inheritDoc}
254     *
255     * <p>This implementation iterates over the specified collection, and adds
256     * each object returned by the iterator to this collection, in turn.
257     *
258     * <p>Note that this implementation will throw an
259     * <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is
260     * overridden (assuming the specified collection is non-empty).
261     *
262     * @throws UnsupportedOperationException {@inheritDoc}
263     * @throws ClassCastException {@inheritDoc}
264     * @throws NullPointerException {@inheritDoc}
265     * @throws IllegalArgumentException {@inheritDoc}
266     * @throws IllegalStateException {@inheritDoc}
267     *
268     * @see #add(Object)
269     */
270     public boolean addAll(Collection<? extends E> c) {
271     boolean modified = false;
272     Iterator<? extends E> e = c.iterator();
273     while (e.hasNext()) {
274     if (add(e.next()))
275     modified = true;
276     }
277     return modified;
278     }
279    
280     /**
281     * {@inheritDoc}
282     *
283     * <p>This implementation iterates over this collection, checking each
284     * element returned by the iterator in turn to see if it's contained
285     * in the specified collection. If it's so contained, it's removed from
286     * this collection with the iterator's <tt>remove</tt> method.
287     *
288     * <p>Note that this implementation will throw an
289     * <tt>UnsupportedOperationException</tt> if the iterator returned by the
290     * <tt>iterator</tt> method does not implement the <tt>remove</tt> method
291     * and this collection contains one or more elements in common with the
292     * specified collection.
293     *
294     * @throws UnsupportedOperationException {@inheritDoc}
295     * @throws ClassCastException {@inheritDoc}
296     * @throws NullPointerException {@inheritDoc}
297     *
298     * @see #remove(Object)
299     * @see #contains(Object)
300     */
301     public boolean removeAll(Collection<?> c) {
302     boolean modified = false;
303     Iterator<?> e = iterator();
304     while (e.hasNext()) {
305     if (c.contains(e.next())) {
306     e.remove();
307     modified = true;
308     }
309     }
310     return modified;
311     }
312    
313     /**
314     * {@inheritDoc}
315     *
316     * <p>This implementation iterates over this collection, checking each
317     * element returned by the iterator in turn to see if it's contained
318     * in the specified collection. If it's not so contained, it's removed
319     * from this collection with the iterator's <tt>remove</tt> method.
320     *
321     * <p>Note that this implementation will throw an
322     * <tt>UnsupportedOperationException</tt> if the iterator returned by the
323     * <tt>iterator</tt> method does not implement the <tt>remove</tt> method
324     * and this collection contains one or more elements not present in the
325     * specified collection.
326     *
327     * @throws UnsupportedOperationException {@inheritDoc}
328     * @throws ClassCastException {@inheritDoc}
329     * @throws NullPointerException {@inheritDoc}
330     *
331     * @see #remove(Object)
332     * @see #contains(Object)
333     */
334     public boolean retainAll(Collection<?> c) {
335     boolean modified = false;
336     Iterator<E> e = iterator();
337     while (e.hasNext()) {
338     if (!c.contains(e.next())) {
339     e.remove();
340     modified = true;
341     }
342     }
343     return modified;
344     }
345    
346     /**
347     * {@inheritDoc}
348     *
349     * <p>This implementation iterates over this collection, removing each
350     * element using the <tt>Iterator.remove</tt> operation. Most
351     * implementations will probably choose to override this method for
352     * efficiency.
353     *
354     * <p>Note that this implementation will throw an
355     * <tt>UnsupportedOperationException</tt> if the iterator returned by this
356     * collection's <tt>iterator</tt> method does not implement the
357     * <tt>remove</tt> method and this collection is non-empty.
358     *
359     * @throws UnsupportedOperationException {@inheritDoc}
360     */
361     public void clear() {
362     Iterator<E> e = iterator();
363     while (e.hasNext()) {
364     e.next();
365     e.remove();
366     }
367     }
368    
369    
370     // String conversion
371    
372     /**
373     * Returns a string representation of this collection. The string
374     * representation consists of a list of the collection's elements in the
375     * order they are returned by its iterator, enclosed in square brackets
376     * (<tt>"[]"</tt>). Adjacent elements are separated by the characters
377     * <tt>", "</tt> (comma and space). Elements are converted to strings as
378     * by {@link String#valueOf(Object)}.
379     *
380     * @return a string representation of this collection
381     */
382     public String toString() {
383     Iterator<E> i = iterator();
384     if (! i.hasNext())
385     return "[]";
386    
387     StringBuilder sb = new StringBuilder();
388     sb.append('[');
389     for (;;) {
390     E e = i.next();
391     sb.append(e == this ? "(this Collection)" : e);
392     if (! i.hasNext())
393     return sb.append(']').toString();
394     sb.append(", ");
395     }
396     }
397    
398     }