001: /*
002: * @(#)AbstractCollection.java 1.23 06/10/10
003: *
004: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: *
026: */
027:
028: package java.util;
029:
030: /**
031: * This class provides a skeletal implementation of the <tt>Collection</tt>
032: * interface, to minimize the effort required to implement this interface. <p>
033: *
034: * To implement an unmodifiable collection, the programmer needs only to
035: * extend this class and provide implementations for the <tt>iterator</tt> and
036: * <tt>size</tt> methods. (The iterator returned by the <tt>iterator</tt>
037: * method must implement <tt>hasNext</tt> and <tt>next</tt>.)<p>
038: *
039: * To implement a modifiable collection, the programmer must additionally
040: * override this class's <tt>add</tt> method (which otherwise throws an
041: * <tt>UnsupportedOperationException</tt>), and the iterator returned by the
042: * <tt>iterator</tt> method must additionally implement its <tt>remove</tt>
043: * method.<p>
044: *
045: * The programmer should generally provide a void (no argument) and
046: * <tt>Collection</tt> constructor, as per the recommendation in the
047: * <tt>Collection</tt> interface specification.<p>
048: *
049: * The documentation for each non-abstract methods in this class describes its
050: * implementation in detail. Each of these methods may be overridden if
051: * the collection being implemented admits a more efficient implementation.<p>
052: *
053: * This class is a member of the
054: * <a href="{@docRoot}/../guide/collections/index.html">
055: * Java Collections Framework</a>.
056: *
057: * @author Josh Bloch
058: * @version 1.16, 02/02/00
059: * @see Collection
060: * @since 1.2
061: */
062:
063: public abstract class AbstractCollection implements Collection {
064: /**
065: * Sole constructor. (For invocation by subclass constructors, typically
066: * implicit.)
067: */
068: protected AbstractCollection() {
069: }
070:
071: // Query Operations
072:
073: /**
074: * Returns an iterator over the elements contained in this collection.
075: *
076: * @return an iterator over the elements contained in this collection.
077: */
078: public abstract Iterator iterator();
079:
080: /**
081: * Returns the number of elements in this collection. If the collection
082: * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns
083: * <tt>Integer.MAX_VALUE</tt>.
084: *
085: * @return the number of elements in this collection.
086: */
087: public abstract int size();
088:
089: /**
090: * Returns <tt>true</tt> if this collection contains no elements.<p>
091: *
092: * This implementation returns <tt>size() == 0</tt>.
093: *
094: * @return <tt>true</tt> if this collection contains no elements.
095: */
096: public boolean isEmpty() {
097: return size() == 0;
098: }
099:
100: /**
101: * Returns <tt>true</tt> if this collection contains the specified
102: * element. More formally, returns <tt>true</tt> if and only if this
103: * collection contains at least one element <tt>e</tt> such that
104: * <tt>(o==null ? e==null : o.equals(e))</tt>.<p>
105: *
106: * This implementation iterates over the elements in the collection,
107: * checking each element in turn for equality with the specified element.
108: *
109: * @param o object to be checked for containment in this collection.
110: * @return <tt>true</tt> if this collection contains the specified element.
111: */
112: public boolean contains(Object o) {
113: Iterator e = iterator();
114: if (o == null) {
115: while (e.hasNext())
116: if (e.next() == null)
117: return true;
118: } else {
119: while (e.hasNext())
120: if (o.equals(e.next()))
121: return true;
122: }
123: return false;
124: }
125:
126: /**
127: * Returns an array containing all of the elements in this collection. If
128: * the collection makes any guarantees as to what order its elements are
129: * returned by its iterator, this method must return the elements in the
130: * same order. The returned array will be "safe" in that no references to
131: * it are maintained by the collection. (In other words, this method must
132: * allocate a new array even if the collection is backed by an Array).
133: * The caller is thus free to modify the returned array.<p>
134: *
135: * This implementation allocates the array to be returned, and iterates
136: * over the elements in the collection, storing each object reference in
137: * the next consecutive element of the array, starting with element 0.
138: *
139: * @return an array containing all of the elements in this collection.
140: */
141: public Object[] toArray() {
142: Object[] result = new Object[size()];
143: Iterator e = iterator();
144: for (int i = 0; e.hasNext(); i++)
145: result[i] = e.next();
146: return result;
147: }
148:
149: /**
150: * Returns an array containing all of the elements in this collection;
151: * the runtime type of the returned array is that of the specified array.
152: * If the collection fits in the specified array, it is returned therein.
153: * Otherwise, a new array is allocated with the runtime type of the
154: * specified array and the size of this collection.<p>
155: *
156: * If the collection fits in the specified array with room to spare (i.e.,
157: * the array has more elements than the collection), the element in the
158: * array immediately following the end of the collection is set to
159: * <tt>null</tt>. This is useful in determining the length of the
160: * collection <i>only</i> if the caller knows that the collection does
161: * not contain any <tt>null</tt> elements.)<p>
162: *
163: * If this collection makes any guarantees as to what order its elements
164: * are returned by its iterator, this method must return the elements in
165: * the same order. <p>
166: *
167: * This implementation checks if the array is large enough to contain the
168: * collection; if not, it allocates a new array of the correct size and
169: * type (using reflection). Then, it iterates over the collection,
170: * storing each object reference in the next consecutive element of the
171: * array, starting with element 0. If the array is larger than the
172: * collection, a <tt>null</tt> is stored in the first location after the
173: * end of the collection.
174: *
175: * @param a the array into which the elements of the collection are to
176: * be stored, if it is big enough; otherwise, a new array of the
177: * same runtime type is allocated for this purpose.
178: * @return an array containing the elements of the collection.
179: *
180: * @throws NullPointerException if the specified array is <tt>null</tt>.
181: *
182: * @throws ArrayStoreException if the runtime type of the specified array
183: * is not a supertype of the runtime type of every element in this
184: * collection.
185: */
186: public Object[] toArray(Object a[]) {
187: int size = size();
188: if (a.length < size)
189: a = (Object[]) java.lang.reflect.Array.newInstance(a
190: .getClass().getComponentType(), size);
191:
192: Iterator it = iterator();
193: for (int i = 0; i < size; i++)
194: a[i] = it.next();
195:
196: if (a.length > size)
197: a[size] = null;
198:
199: return a;
200: }
201:
202: // Modification Operations
203:
204: /**
205: * Ensures that this collection contains the specified element (optional
206: * operation). Returns <tt>true</tt> if the collection changed as a
207: * result of the call. (Returns <tt>false</tt> if this collection does
208: * not permit duplicates and already contains the specified element.)
209: * Collections that support this operation may place limitations on what
210: * elements may be added to the collection. In particular, some
211: * collections will refuse to add <tt>null</tt> elements, and others will
212: * impose restrictions on the type of elements that may be added.
213: * Collection classes should clearly specify in their documentation any
214: * restrictions on what elements may be added.<p>
215: *
216: * This implementation always throws an
217: * <tt>UnsupportedOperationException</tt>.
218: *
219: * @param o element whose presence in this collection is to be ensured.
220: * @return <tt>true</tt> if the collection changed as a result of the call.
221: *
222: * @throws UnsupportedOperationException if the <tt>add</tt> method is not
223: * supported by this collection.
224: *
225: * @throws NullPointerException if this collection does not permit
226: * <tt>null</tt> elements, and the specified element is
227: * <tt>null</tt>.
228: *
229: * @throws ClassCastException if the class of the specified element
230: * prevents it from being added to this collection.
231: *
232: * @throws IllegalArgumentException if some aspect of this element
233: * prevents it from being added to this collection.
234: */
235: public boolean add(Object o) {
236: throw new UnsupportedOperationException();
237: }
238:
239: /**
240: * Removes a single instance of the specified element from this
241: * collection, if it is present (optional operation). More formally,
242: * removes an element <tt>e</tt> such that <tt>(o==null ? e==null :
243: * o.equals(e))</tt>, if the collection contains one or more such
244: * elements. Returns <tt>true</tt> if the collection contained the
245: * specified element (or equivalently, if the collection changed as a
246: * result of the call).<p>
247: *
248: * This implementation iterates over the collection looking for the
249: * specified element. If it finds the element, it removes the element
250: * from the collection using the iterator's remove method.<p>
251: *
252: * Note that this implementation throws an
253: * <tt>UnsupportedOperationException</tt> if the iterator returned by this
254: * collection's iterator method does not implement the <tt>remove</tt>
255: * method and this collection contains the specified object.
256: *
257: * @param o element to be removed from this collection, if present.
258: * @return <tt>true</tt> if the collection contained the specified
259: * element.
260: * @throws UnsupportedOperationException if the <tt>remove</tt> method is
261: * not supported by this collection.
262: */
263: public boolean remove(Object o) {
264: Iterator e = iterator();
265: if (o == null) {
266: while (e.hasNext()) {
267: if (e.next() == null) {
268: e.remove();
269: return true;
270: }
271: }
272: } else {
273: while (e.hasNext()) {
274: if (o.equals(e.next())) {
275: e.remove();
276: return true;
277: }
278: }
279: }
280: return false;
281: }
282:
283: // Bulk Operations
284:
285: /**
286: * Returns <tt>true</tt> if this collection contains all of the elements
287: * in the specified collection. <p>
288: *
289: * This implementation iterates over the specified collection, checking
290: * each element returned by the iterator in turn to see if it's
291: * contained in this collection. If all elements are so contained
292: * <tt>true</tt> is returned, otherwise <tt>false</tt>.
293: *
294: * @param c collection to be checked for containment in this collection.
295: * @return <tt>true</tt> if this collection contains all of the elements
296: * in the specified collection.
297: * @throws NullPointerException if the specified collection is null.
298: *
299: * @see #contains(Object)
300: */
301: public boolean containsAll(Collection c) {
302: Iterator e = c.iterator();
303: while (e.hasNext())
304: if (!contains(e.next()))
305: return false;
306:
307: return true;
308: }
309:
310: /**
311: * Adds all of the elements in the specified collection to this collection
312: * (optional operation). The behavior of this operation is undefined if
313: * the specified collection is modified while the operation is in
314: * progress. (This implies that the behavior of this call is undefined if
315: * the specified collection is this collection, and this collection is
316: * nonempty.) <p>
317: *
318: * This implementation iterates over the specified collection, and adds
319: * each object returned by the iterator to this collection, in turn.<p>
320: *
321: * Note that this implementation will throw an
322: * <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is
323: * overridden (assuming the specified collection is non-empty).
324: *
325: * @param c collection whose elements are to be added to this collection.
326: * @return <tt>true</tt> if this collection changed as a result of the
327: * call.
328: * @throws UnsupportedOperationException if this collection does not
329: * support the <tt>addAll</tt> method.
330: * @throws NullPointerException if the specified collection is null.
331: *
332: * @see #add(Object)
333: */
334: public boolean addAll(Collection c) {
335: boolean modified = false;
336: Iterator e = c.iterator();
337: while (e.hasNext()) {
338: if (add(e.next()))
339: modified = true;
340: }
341: return modified;
342: }
343:
344: /**
345: * Removes from this collection all of its elements that are contained in
346: * the specified collection (optional operation). <p>
347: *
348: * This implementation iterates over this collection, checking each
349: * element returned by the iterator in turn to see if it's contained
350: * in the specified collection. If it's so contained, it's removed from
351: * this collection with the iterator's <tt>remove</tt> method.<p>
352: *
353: * Note that this implementation will throw an
354: * <tt>UnsupportedOperationException</tt> if the iterator returned by the
355: * <tt>iterator</tt> method does not implement the <tt>remove</tt> method
356: * and this collection contains one or more elements in common with the
357: * specified collection.
358: *
359: * @param c elements to be removed from this collection.
360: * @return <tt>true</tt> if this collection changed as a result of the
361: * call.
362: * @throws UnsupportedOperationException if the <tt>removeAll</tt> method
363: * is not supported by this collection.
364: * @throws NullPointerException if the specified collection is null.
365: *
366: * @see #remove(Object)
367: * @see #contains(Object)
368: */
369: public boolean removeAll(Collection c) {
370: boolean modified = false;
371: Iterator e = iterator();
372: while (e.hasNext()) {
373: if (c.contains(e.next())) {
374: e.remove();
375: modified = true;
376: }
377: }
378: return modified;
379: }
380:
381: /**
382: * Retains only the elements in this collection that are contained in the
383: * specified collection (optional operation). In other words, removes
384: * from this collection all of its elements that are not contained in the
385: * specified collection. <p>
386: *
387: * This implementation iterates over this collection, checking each
388: * element returned by the iterator in turn to see if it's contained
389: * in the specified collection. If it's not so contained, it's removed
390: * from this collection with the iterator's <tt>remove</tt> method.<p>
391: *
392: * Note that this implementation will throw an
393: * <tt>UnsupportedOperationException</tt> if the iterator returned by the
394: * <tt>iterator</tt> method does not implement the <tt>remove</tt> method
395: * and this collection contains one or more elements not present in the
396: * specified collection.
397: *
398: * @param c elements to be retained in this collection.
399: * @return <tt>true</tt> if this collection changed as a result of the
400: * call.
401: * @throws UnsupportedOperationException if the <tt>retainAll</tt> method
402: * is not supported by this Collection.
403: * @throws NullPointerException if the specified collection is null.
404: *
405: * @see #remove(Object)
406: * @see #contains(Object)
407: */
408: public boolean retainAll(Collection c) {
409: boolean modified = false;
410: Iterator e = iterator();
411: while (e.hasNext()) {
412: if (!c.contains(e.next())) {
413: e.remove();
414: modified = true;
415: }
416: }
417: return modified;
418: }
419:
420: /**
421: * Removes all of the elements from this collection (optional operation).
422: * The collection will be empty after this call returns (unless it throws
423: * an exception).<p>
424: *
425: * This implementation iterates over this collection, removing each
426: * element using the <tt>Iterator.remove</tt> operation. Most
427: * implementations will probably choose to override this method for
428: * efficiency.<p>
429: *
430: * Note that this implementation will throw an
431: * <tt>UnsupportedOperationException</tt> if the iterator returned by this
432: * collection's <tt>iterator</tt> method does not implement the
433: * <tt>remove</tt> method and this collection is non-empty.
434: *
435: * @throws UnsupportedOperationException if the <tt>clear</tt> method is
436: * not supported by this collection.
437: */
438: public void clear() {
439: Iterator e = iterator();
440: while (e.hasNext()) {
441: e.next();
442: e.remove();
443: }
444: }
445:
446: // String conversion
447:
448: /**
449: * Returns a string representation of this collection. The string
450: * representation consists of a list of the collection's elements in the
451: * order they are returned by its iterator, enclosed in square brackets
452: * (<tt>"[]"</tt>). Adjacent elements are separated by the characters
453: * <tt>", "</tt> (comma and space). Elements are converted to strings as
454: * by <tt>String.valueOf(Object)</tt>.<p>
455: *
456: * This implementation creates an empty string buffer, appends a left
457: * square bracket, and iterates over the collection appending the string
458: * representation of each element in turn. After appending each element
459: * except the last, the string <tt>", "</tt> is appended. Finally a right
460: * bracket is appended. A string is obtained from the string buffer, and
461: * returned.
462: *
463: * @return a string representation of this collection.
464: */
465: public String toString() {
466: StringBuffer buf = new StringBuffer();
467: buf.append("[");
468:
469: Iterator i = iterator();
470: boolean hasNext = i.hasNext();
471: while (hasNext) {
472: Object o = i.next();
473: buf.append(o == this ? "(this Collection)" : String
474: .valueOf(o));
475: hasNext = i.hasNext();
476: if (hasNext)
477: buf.append(", ");
478: }
479:
480: buf.append("]");
481: return buf.toString();
482: }
483: }
|