source: trunk/gcc/libjava/java/util/AbstractCollection.java

Last change on this file was 2, checked in by bird, 22 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 17.0 KB
Line 
1/* AbstractCollection.java -- Abstract implementation of most of Collection
2 Copyright (C) 1998, 2000, 2001 Free Software Foundation, Inc.
3
4This file is part of GNU Classpath.
5
6GNU Classpath is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU Classpath is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU Classpath; see the file COPYING. If not, write to the
18Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
1902111-1307 USA.
20
21Linking this library statically or dynamically with other modules is
22making a combined work based on this library. Thus, the terms and
23conditions of the GNU General Public License cover the whole
24combination.
25
26As a special exception, the copyright holders of this library give you
27permission to link this library with independent modules to produce an
28executable, regardless of the license terms of these independent
29modules, and to copy and distribute the resulting executable under
30terms of your choice, provided that you also meet, for each linked
31independent module, the terms and conditions of the license of that
32module. An independent module is a module which is not derived from
33or based on this library. If you modify this library, you may extend
34this exception to your version of the library, but you are not
35obligated to do so. If you do not wish to do so, delete this
36exception statement from your version. */
37
38
39package java.util;
40
41import java.lang.reflect.Array;
42
43/**
44 * A basic implementation of most of the methods in the Collection interface to
45 * make it easier to create a collection. To create an unmodifiable Collection,
46 * just subclass AbstractCollection and provide implementations of the
47 * iterator() and size() methods. The Iterator returned by iterator() need only
48 * provide implementations of hasNext() and next() (that is, it may throw an
49 * UnsupportedOperationException if remove() is called). To create a modifiable
50 * Collection, you must in addition provide an implementation of the
51 * add(Object) method and the Iterator returned by iterator() must provide an
52 * implementation of remove(). Other methods should be overridden if the
53 * backing data structure allows for a more efficient implementation. The
54 * precise implementation used by AbstractCollection is documented, so that
55 * subclasses can tell which methods could be implemented more efficiently.
56 * <p>
57 *
58 * The programmer should provide a no-argument constructor, and one that
59 * accepts another Collection, as recommended by the Collection interface.
60 * Unfortunately, there is no way to enforce this in Java.
61 *
62 * @author Original author unknown
63 * @author Bryce McKinlay
64 * @author Eric Blake <ebb9@email.byu.edu>
65 * @see Collection
66 * @see AbstractSet
67 * @see AbstractList
68 * @since 1.2
69 * @status updated to 1.4
70 */
71public abstract class AbstractCollection implements Collection
72{
73 /**
74 * The main constructor, for use by subclasses.
75 */
76 protected AbstractCollection()
77 {
78 }
79
80 /**
81 * Return an Iterator over this collection. The iterator must provide the
82 * hasNext and next methods and should in addition provide remove if the
83 * collection is modifiable.
84 *
85 * @return an iterator
86 */
87 public abstract Iterator iterator();
88
89 /**
90 * Return the number of elements in this collection. If there are more than
91 * Integer.MAX_VALUE elements, return Integer.MAX_VALUE.
92 *
93 * @return the size
94 */
95 public abstract int size();
96
97 /**
98 * Add an object to the collection (optional operation). This implementation
99 * always throws an UnsupportedOperationException - it should be
100 * overridden if the collection is to be modifiable. If the collection
101 * does not accept duplicates, simply return false. Collections may specify
102 * limitations on what may be added.
103 *
104 * @param o the object to add
105 * @return true if the add operation caused the Collection to change
106 * @throws UnsupportedOperationException if the add operation is not
107 * supported on this collection
108 * @throws NullPointerException if the collection does not support null
109 * @throws ClassCastException if the object is of the wrong type
110 * @throws IllegalArgumentException if some aspect of the object prevents
111 * it from being added
112 */
113 public boolean add(Object o)
114 {
115 throw new UnsupportedOperationException();
116 }
117
118 /**
119 * Add all the elements of a given collection to this collection (optional
120 * operation). This implementation obtains an Iterator over the given
121 * collection and iterates over it, adding each element with the
122 * add(Object) method (thus this method will fail with an
123 * UnsupportedOperationException if the add method does). The behavior is
124 * unspecified if the specified collection is modified during the iteration,
125 * including the special case of trying addAll(this) on a non-empty
126 * collection.
127 *
128 * @param c the collection to add the elements of to this collection
129 * @return true if the add operation caused the Collection to change
130 * @throws UnsupportedOperationException if the add operation is not
131 * supported on this collection
132 * @throws NullPointerException if this collection does not support null,
133 * or if the specified collection is null
134 * @throws ClassCastException if an object in c is of the wrong type
135 * @throws IllegalArgumentException if some aspect of an object in c prevents
136 * it from being added
137 * @see #add(Object)
138 */
139 public boolean addAll(Collection c)
140 {
141 Iterator itr = c.iterator();
142 boolean modified = false;
143 int pos = c.size();
144 while (--pos >= 0)
145 modified |= add(itr.next());
146 return modified;
147 }
148
149 /**
150 * Remove all elements from the collection (optional operation). This
151 * implementation obtains an iterator over the collection and calls next
152 * and remove on it repeatedly (thus this method will fail with an
153 * UnsupportedOperationException if the Iterator's remove method does)
154 * until there are no more elements to remove.
155 * Many implementations will have a faster way of doing this.
156 *
157 * @throws UnsupportedOperationException if the Iterator returned by
158 * iterator does not provide an implementation of remove
159 * @see Iterator#remove()
160 */
161 public void clear()
162 {
163 Iterator itr = iterator();
164 int pos = size();
165 while (--pos >= 0)
166 {
167 itr.next();
168 itr.remove();
169 }
170 }
171
172 /**
173 * Test whether this collection contains a given object. That is, if the
174 * collection has an element e such that (o == null ? e == null :
175 * o.equals(e)). This implementation obtains an iterator over the collection
176 * and iterates over it, testing each element for equality with the given
177 * object. If it is equal, true is returned. Otherwise false is returned when
178 * the end of the collection is reached.
179 *
180 * @param o the object to remove from this collection
181 * @return true if this collection contains an object equal to o
182 */
183 public boolean contains(Object o)
184 {
185 Iterator itr = iterator();
186 int pos = size();
187 while (--pos >= 0)
188 if (equals(o, itr.next()))
189 return true;
190 return false;
191 }
192
193 /**
194 * Tests whether this collection contains all the elements in a given
195 * collection. This implementation iterates over the given collection,
196 * testing whether each element is contained in this collection. If any one
197 * is not, false is returned. Otherwise true is returned.
198 *
199 * @param c the collection to test against
200 * @return true if this collection contains all the elements in the given
201 * collection
202 * @throws NullPointerException if the given collection is null
203 * @see #contains(Object)
204 */
205 public boolean containsAll(Collection c)
206 {
207 Iterator itr = c.iterator();
208 int pos = c.size();
209 while (--pos >= 0)
210 if (!contains(itr.next()))
211 return false;
212 return true;
213 }
214
215 /**
216 * Test whether this collection is empty. This implementation returns
217 * size() == 0.
218 *
219 * @return true if this collection is empty.
220 * @see #size()
221 */
222 public boolean isEmpty()
223 {
224 return size() == 0;
225 }
226
227 /**
228 * Remove a single instance of an object from this collection (optional
229 * operation). That is, remove one element e such that
230 * <code>(o == null ? e == null : o.equals(e))</code>, if such an element
231 * exists. This implementation obtains an iterator over the collection
232 * and iterates over it, testing each element for equality with the given
233 * object. If it is equal, it is removed by the iterator's remove method
234 * (thus this method will fail with an UnsupportedOperationException if
235 * the Iterator's remove method does). After the first element has been
236 * removed, true is returned; if the end of the collection is reached, false
237 * is returned.
238 *
239 * @param o the object to remove from this collection
240 * @return true if the remove operation caused the Collection to change, or
241 * equivalently if the collection did contain o.
242 * @throws UnsupportedOperationException if this collection's Iterator
243 * does not support the remove method
244 * @see Iterator#remove()
245 */
246 public boolean remove(Object o)
247 {
248 Iterator itr = iterator();
249 int pos = size();
250 while (--pos >= 0)
251 if (equals(o, itr.next()))
252 {
253 itr.remove();
254 return true;
255 }
256 return false;
257 }
258
259 /**
260 * Remove from this collection all its elements that are contained in a given
261 * collection (optional operation). This implementation iterates over this
262 * collection, and for each element tests if it is contained in the given
263 * collection. If so, it is removed by the Iterator's remove method (thus
264 * this method will fail with an UnsupportedOperationException if the
265 * Iterator's remove method does).
266 *
267 * @param c the collection to remove the elements of
268 * @return true if the remove operation caused the Collection to change
269 * @throws UnsupportedOperationException if this collection's Iterator
270 * does not support the remove method
271 * @see Iterator#remove()
272 */
273 public boolean removeAll(Collection c)
274 {
275 return removeAllInternal(c);
276 }
277
278 /**
279 * Remove from this collection all its elements that are contained in a given
280 * collection (optional operation). This implementation iterates over this
281 * collection, and for each element tests if it is contained in the given
282 * collection. If so, it is removed by the Iterator's remove method (thus
283 * this method will fail with an UnsupportedOperationException if the
284 * Iterator's remove method does). This method is necessary for ArrayList,
285 * which cannot publicly override removeAll but can optimize this call.
286 *
287 * @param c the collection to remove the elements of
288 * @return true if the remove operation caused the Collection to change
289 * @throws UnsupportedOperationException if this collection's Iterator
290 * does not support the remove method
291 * @see Iterator#remove()
292 */
293 boolean removeAllInternal(Collection c)
294 {
295 Iterator itr = iterator();
296 boolean modified = false;
297 int pos = size();
298 while (--pos >= 0)
299 if (c.contains(itr.next()))
300 {
301 itr.remove();
302 modified = true;
303 }
304 return modified;
305 }
306
307 /**
308 * Remove from this collection all its elements that are not contained in a
309 * given collection (optional operation). This implementation iterates over
310 * this collection, and for each element tests if it is contained in the
311 * given collection. If not, it is removed by the Iterator's remove method
312 * (thus this method will fail with an UnsupportedOperationException if
313 * the Iterator's remove method does).
314 *
315 * @param c the collection to retain the elements of
316 * @return true if the remove operation caused the Collection to change
317 * @throws UnsupportedOperationException if this collection's Iterator
318 * does not support the remove method
319 * @see Iterator#remove()
320 */
321 public boolean retainAll(Collection c)
322 {
323 return retainAllInternal(c);
324 }
325
326 /**
327 * Remove from this collection all its elements that are not contained in a
328 * given collection (optional operation). This implementation iterates over
329 * this collection, and for each element tests if it is contained in the
330 * given collection. If not, it is removed by the Iterator's remove method
331 * (thus this method will fail with an UnsupportedOperationException if
332 * the Iterator's remove method does). This method is necessary for
333 * ArrayList, which cannot publicly override retainAll but can optimize
334 * this call.
335 *
336 * @param c the collection to retain the elements of
337 * @return true if the remove operation caused the Collection to change
338 * @throws UnsupportedOperationException if this collection's Iterator
339 * does not support the remove method
340 * @see Iterator#remove()
341 */
342 boolean retainAllInternal(Collection c)
343 {
344 Iterator itr = iterator();
345 boolean modified = false;
346 int pos = size();
347 while (--pos >= 0)
348 if (!c.contains(itr.next()))
349 {
350 itr.remove();
351 modified = true;
352 }
353 return modified;
354 }
355
356 /**
357 * Return an array containing the elements of this collection. This
358 * implementation creates an Object array of size size() and then iterates
359 * over the collection, setting each element of the array from the value
360 * returned by the iterator. The returned array is safe, and is not backed
361 * by the collection.
362 *
363 * @return an array containing the elements of this collection
364 */
365 public Object[] toArray()
366 {
367 Iterator itr = iterator();
368 int size = size();
369 Object[] a = new Object[size];
370 for (int pos = 0; pos < size; pos++)
371 a[pos] = itr.next();
372 return a;
373 }
374
375 /**
376 * Copy the collection into a given array if it will fit, or into a
377 * dynamically created array of the same run-time type as the given array if
378 * not. If there is space remaining in the array, the first element after the
379 * end of the collection is set to null (this is only useful if the
380 * collection is known to contain no null elements, however). This
381 * implementation first tests whether the given array is large enough to hold
382 * all the elements of the collection. If not, the reflection API is used to
383 * allocate a new array of the same run-time type. Next an iterator is
384 * obtained over the collection and the elements are placed in the array as
385 * they are returned by the iterator. Finally the first spare element, if
386 * any, of the array is set to null, and the created array is returned.
387 * The returned array is safe; it is not backed by the collection. Note that
388 * null may not mark the last element, if the collection allows null
389 * elements.
390 *
391 * @param a the array to copy into, or of the correct run-time type
392 * @return the array that was produced
393 * @throws NullPointerException if the given array is null
394 * @throws ArrayStoreException if the type of the array precludes holding
395 * one of the elements of the Collection
396 */
397 public Object[] toArray(Object[] a)
398 {
399 int size = size();
400 if (a.length < size)
401 a = (Object[]) Array.newInstance(a.getClass().getComponentType(),
402 size);
403 else if (a.length > size)
404 a[size] = null;
405
406 Iterator itr = iterator();
407 for (int pos = 0; pos < size; pos++)
408 a[pos] = itr.next();
409
410 return a;
411 }
412
413 /**
414 * Creates a String representation of the Collection. The string returned is
415 * of the form "[a, b, ...]" where a and b etc are the results of calling
416 * toString on the elements of the collection. This implementation obtains an
417 * Iterator over the Collection and adds each element to a StringBuffer as it
418 * is returned by the iterator.
419 *
420 * @return a String representation of the Collection
421 */
422 public String toString()
423 {
424 Iterator itr = iterator();
425 StringBuffer r = new StringBuffer("[");
426 for (int pos = size(); pos > 0; pos--)
427 {
428 r.append(itr.next());
429 if (pos > 1)
430 r.append(", ");
431 }
432 r.append("]");
433 return r.toString();
434 }
435
436 /**
437 * Compare two objects according to Collection semantics.
438 *
439 * @param o1 the first object
440 * @param o2 the second object
441 * @return o1 == null ? o2 == null : o1.equals(o2)
442 */
443 // Package visible for use throughout java.util.
444 // It may be inlined since it is final.
445 static final boolean equals(Object o1, Object o2)
446 {
447 return o1 == null ? o2 == null : o1.equals(o2);
448 }
449
450 /**
451 * Hash an object according to Collection semantics.
452 *
453 * @param o the object to hash
454 * @return o1 == null ? 0 : o1.hashCode()
455 */
456 // Package visible for use throughout java.util.
457 // It may be inlined since it is final.
458 static final int hashCode(Object o)
459 {
460 return o == null ? 0 : o.hashCode();
461 }
462}
Note: See TracBrowser for help on using the repository browser.