ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/AbstractCollection.java
Revision: 1.2
Committed: Wed Nov 23 05:33:25 2005 UTC (18 years, 6 months ago) by jsr166
Branch: MAIN
Changes since 1.1: +5 -5 lines
Log Message:
whitespace

File Contents

# User Rev Content
1 dl 1.1 /*
2     * @(#)AbstractCollection.java 1.33 05/09/09
3     *
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     Iterator 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     T[] r = a.length >= size? a :
133     (T[])java.lang.reflect.Array
134     .newInstance(a.getClass().getComponentType(), size);
135     int i = 0;
136     Iterator 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     * Reallocate the array being used within toArray that has a
149     * different number of elements than expected, and finish filling
150     * it if necessary
151     * @param r the array
152     * @param i the next array index to fill
153     * @param it the in-progress iterator over the collection
154     * @return larger array containing same elements
155     */
156     private static <T> T[] resizeAndFinishToArray(T[] r, int i, Iterator it) {
157 jsr166 1.2 while (it.hasNext()) {
158 dl 1.1 int cap = r.length;
159     if (i < cap)
160     r[i++] = (T)it.next();
161     else if (cap < Integer.MAX_VALUE) { // expand
162     int newCap = (cap * 3) / 2 + 1;
163     if (newCap <= cap) // integer overflow
164     newCap = Integer.MAX_VALUE;
165     r = Arrays.copyOf(r, newCap);
166     } else // can't expand
167     throw new OutOfMemoryError("Required array size too large");
168     }
169     // trim if overallocated
170 jsr166 1.2 return i == r.length? r : Arrays.copyOf(r, i);
171 dl 1.1 }
172    
173     // Modification Operations
174    
175     /**
176     * {@inheritDoc}
177     *
178     * <p>This implementation always throws an
179     * <tt>UnsupportedOperationException</tt>.
180     *
181     * @throws UnsupportedOperationException {@inheritDoc}
182     * @throws ClassCastException {@inheritDoc}
183     * @throws NullPointerException {@inheritDoc}
184     * @throws IllegalArgumentException {@inheritDoc}
185     * @throws IllegalStateException {@inheritDoc}
186     */
187     public boolean add(E e) {
188     throw new UnsupportedOperationException();
189     }
190    
191     /**
192     * {@inheritDoc}
193     *
194     * <p>This implementation iterates over the collection looking for the
195     * specified element. If it finds the element, it removes the element
196     * from the collection using the iterator's remove method.
197     *
198     * <p>Note that this implementation throws an
199     * <tt>UnsupportedOperationException</tt> if the iterator returned by this
200     * collection's iterator method does not implement the <tt>remove</tt>
201     * method and this collection contains the specified object.
202     *
203     * @throws UnsupportedOperationException {@inheritDoc}
204     * @throws ClassCastException {@inheritDoc}
205     * @throws NullPointerException {@inheritDoc}
206     */
207     public boolean remove(Object o) {
208     Iterator<E> e = iterator();
209     if (o==null) {
210     while (e.hasNext()) {
211     if (e.next()==null) {
212     e.remove();
213     return true;
214     }
215     }
216     } else {
217     while (e.hasNext()) {
218     if (o.equals(e.next())) {
219     e.remove();
220     return true;
221     }
222     }
223     }
224     return false;
225     }
226    
227    
228     // Bulk Operations
229    
230     /**
231     * {@inheritDoc}
232     *
233     * <p>This implementation iterates over the specified collection,
234     * checking each element returned by the iterator in turn to see
235     * if it's contained in this collection. If all elements are so
236     * contained <tt>true</tt> is returned, otherwise <tt>false</tt>.
237     *
238     * @throws ClassCastException {@inheritDoc}
239     * @throws NullPointerException {@inheritDoc}
240     * @see #contains(Object)
241     */
242     public boolean containsAll(Collection<?> c) {
243     Iterator<?> e = c.iterator();
244     while (e.hasNext())
245     if (!contains(e.next()))
246     return false;
247     return true;
248     }
249    
250     /**
251     * {@inheritDoc}
252     *
253     * <p>This implementation iterates over the specified collection, and adds
254     * each object returned by the iterator to this collection, in turn.
255     *
256     * <p>Note that this implementation will throw an
257     * <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is
258     * overridden (assuming the specified collection is non-empty).
259     *
260     * @throws UnsupportedOperationException {@inheritDoc}
261     * @throws ClassCastException {@inheritDoc}
262     * @throws NullPointerException {@inheritDoc}
263     * @throws IllegalArgumentException {@inheritDoc}
264     * @throws IllegalStateException {@inheritDoc}
265     *
266     * @see #add(Object)
267     */
268     public boolean addAll(Collection<? extends E> c) {
269     boolean modified = false;
270     Iterator<? extends E> e = c.iterator();
271     while (e.hasNext()) {
272     if (add(e.next()))
273     modified = true;
274     }
275     return modified;
276     }
277    
278     /**
279     * {@inheritDoc}
280     *
281     * <p>This implementation iterates over this collection, checking each
282     * element returned by the iterator in turn to see if it's contained
283     * in the specified collection. If it's so contained, it's removed from
284     * this collection with the iterator's <tt>remove</tt> method.
285     *
286     * <p>Note that this implementation will throw an
287     * <tt>UnsupportedOperationException</tt> if the iterator returned by the
288     * <tt>iterator</tt> method does not implement the <tt>remove</tt> method
289     * and this collection contains one or more elements in common with the
290     * specified collection.
291     *
292     * @throws UnsupportedOperationException {@inheritDoc}
293     * @throws ClassCastException {@inheritDoc}
294     * @throws NullPointerException {@inheritDoc}
295     *
296     * @see #remove(Object)
297     * @see #contains(Object)
298     */
299     public boolean removeAll(Collection<?> c) {
300     boolean modified = false;
301     Iterator<?> e = iterator();
302     while (e.hasNext()) {
303     if (c.contains(e.next())) {
304     e.remove();
305     modified = true;
306     }
307     }
308     return modified;
309     }
310    
311     /**
312     * {@inheritDoc}
313     *
314     * <p>This implementation iterates over this collection, checking each
315     * element returned by the iterator in turn to see if it's contained
316     * in the specified collection. If it's not so contained, it's removed
317     * from this collection with the iterator's <tt>remove</tt> method.
318     *
319     * <p>Note that this implementation will throw an
320     * <tt>UnsupportedOperationException</tt> if the iterator returned by the
321     * <tt>iterator</tt> method does not implement the <tt>remove</tt> method
322     * and this collection contains one or more elements not present in the
323     * specified collection.
324     *
325     * @throws UnsupportedOperationException {@inheritDoc}
326     * @throws ClassCastException {@inheritDoc}
327     * @throws NullPointerException {@inheritDoc}
328     *
329     * @see #remove(Object)
330     * @see #contains(Object)
331     */
332     public boolean retainAll(Collection<?> c) {
333     boolean modified = false;
334     Iterator<E> e = iterator();
335     while (e.hasNext()) {
336     if (!c.contains(e.next())) {
337     e.remove();
338     modified = true;
339     }
340     }
341     return modified;
342     }
343    
344     /**
345     * {@inheritDoc}
346     *
347     * <p>This implementation iterates over this collection, removing each
348     * element using the <tt>Iterator.remove</tt> operation. Most
349     * implementations will probably choose to override this method for
350     * efficiency.
351     *
352     * <p>Note that this implementation will throw an
353     * <tt>UnsupportedOperationException</tt> if the iterator returned by this
354     * collection's <tt>iterator</tt> method does not implement the
355     * <tt>remove</tt> method and this collection is non-empty.
356     *
357     * @throws UnsupportedOperationException {@inheritDoc}
358     */
359     public void clear() {
360     Iterator<E> e = iterator();
361     while (e.hasNext()) {
362     e.next();
363     e.remove();
364     }
365     }
366    
367    
368     // String conversion
369    
370     /**
371     * Returns a string representation of this collection. The string
372     * representation consists of a list of the collection's elements in the
373     * order they are returned by its iterator, enclosed in square brackets
374     * (<tt>"[]"</tt>). Adjacent elements are separated by the characters
375     * <tt>", "</tt> (comma and space). Elements are converted to strings as
376     * by {@link String#valueOf(Object)}.
377     *
378     * @return a string representation of this collection
379     */
380     public String toString() {
381     Iterator<E> i = iterator();
382     if (! i.hasNext())
383     return "[]";
384    
385     StringBuilder sb = new StringBuilder();
386     sb.append('[');
387     for (;;) {
388     E e = i.next();
389     sb.append(e == this ? "(this Collection)" : e);
390     if (! i.hasNext())
391     return sb.append(']').toString();
392     sb.append(", ");
393     }
394     }
395    
396     }