ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/main/java/util/AbstractCollection.java
Revision: 1.5
Committed: Mon Dec 5 02:56:59 2005 UTC (18 years, 5 months ago) by jsr166
Branch: MAIN
Changes since 1.4: +1 -1 lines
Log Message:
copyright update for 2006

File Contents

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