001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: package java.util;
019:
020: import java.lang.reflect.Array;
021:
022: /**
023: * AbstractCollection is an abstract implementation of the Collection interface.
024: * This implementation does not support adding. A subclass must implement the
025: * abstract methods iterator() and size().
026: *
027: * @since 1.2
028: */
029: public abstract class AbstractCollection<E> implements Collection<E> {
030:
031: /**
032: * Constructs a new instance of this AbstractCollection.
033: */
034: protected AbstractCollection() {
035: super ();
036: }
037:
038: /**
039: * If the specified element is not contained within this collection, and
040: * addition of this element succeeds, then true will be returned. If the
041: * specified element is already contained within this collection, or
042: * duplication is not permitted, false will be returned. Different
043: * implementations may add specific limitations on this method to filter
044: * permitted elements. For example, in some implementation, null element may
045: * be denied, and NullPointerException will be thrown out. These limitations
046: * should be explicitly documented by specific collection implementation.
047: *
048: * Add operation is not supported in this implementation, and
049: * UnsupportedOperationException will always be thrown out.
050: *
051: * @param object
052: * the element to be added.
053: * @return true if the collection is changed successfully after invoking
054: * this method. Otherwise, false.
055: * @throws UnsupportedOperationException
056: * if add operation is not supported by this class.
057: * @throws NullPointerException
058: * if null is used to invoke this method, and null is not
059: * permitted by this collection.
060: * @throws ClassCastException
061: * if the class type of the specified element is not compatible
062: * with the permitted class type.
063: * @throws IllegalArgumentException
064: * if limitations of this collection prevent the specified
065: * element from being added
066: */
067: public boolean add(E object) {
068: throw new UnsupportedOperationException();
069: }
070:
071: /**
072: * Adds the objects in the specified Collection to this Collection.
073: *
074: * @param collection
075: * the Collection of objects
076: * @return true if this Collection is modified, false otherwise
077: *
078: * @throws UnsupportedOperationException
079: * when adding to this Collection is not supported
080: * @throws NullPointerException
081: * if null is used to invoke this method
082: */
083: public boolean addAll(Collection<? extends E> collection) {
084: boolean result = false;
085: Iterator<? extends E> it = collection.iterator();
086: while (it.hasNext()) {
087: if (add(it.next())) {
088: result = true;
089: }
090: }
091: return result;
092: }
093:
094: /**
095: * Removes all the elements in this collection. This collection will be
096: * cleared up after this operation. The operation iterates over the
097: * collection, removes every element using Iterator.remove method.
098: *
099: * UnsupportedOperationException will be thrown out if the iterator returned
100: * by this collection does not implement the remove method and the
101: * collection is not zero length.
102: *
103: * @throws UnsupportedOperationException
104: * if this operation is not implemented.
105: */
106: public void clear() {
107: Iterator<E> it = iterator();
108: while (it.hasNext()) {
109: it.next();
110: it.remove();
111: }
112: }
113:
114: /**
115: * Searches this Collection for the specified object.
116: *
117: * @param object
118: * the object to search for
119: * @return true if <code>object</code> is an element of this Collection,
120: * false otherwise
121: */
122: public boolean contains(Object object) {
123: Iterator<E> it = iterator();
124: if (object != null) {
125: while (it.hasNext()) {
126: if (object.equals(it.next())) {
127: return true;
128: }
129: }
130: } else {
131: while (it.hasNext()) {
132: if (it.next() == null) {
133: return true;
134: }
135: }
136: }
137: return false;
138: }
139:
140: /**
141: * Searches this Collection for all objects in the specified Collection.
142: *
143: * @param collection
144: * the Collection of objects
145: * @return true if all objects in the specified Collection are elements of
146: * this Collection, false otherwise
147: * @throws NullPointerException
148: * if null is used to invoke this method
149: */
150: public boolean containsAll(Collection<?> collection) {
151: Iterator<?> it = collection.iterator();
152: while (it.hasNext()) {
153: if (!contains(it.next())) {
154: return false;
155: }
156: }
157: return true;
158: }
159:
160: /**
161: * Returns true if the collection has no element, otherwise false.
162: *
163: * @return true if the collection has no element.
164: */
165: public boolean isEmpty() {
166: return size() == 0;
167: }
168:
169: /**
170: * Answers an Iterator on the elements of this Collection. A subclass must
171: * implement the abstract methods iterator() and size().
172: *
173: * @return an Iterator on the elements of this Collection
174: *
175: * @see Iterator
176: */
177: public abstract Iterator<E> iterator();
178:
179: /**
180: * Removes the first occurrence of the specified object from this
181: * Collection. This operation traverses over the collection, looking for the
182: * specified object. Once the object is found, the object will be removed
183: * from the collection using the iterator's remove method.
184: *
185: * This collection will throw an UnsupportedOperationException if the
186: * iterator returned does not implement remove method, and the specified
187: * object is in this collection.
188: *
189: * @param object
190: * the object to remove
191: * @return true if this Collection is modified, false otherwise
192: *
193: * @throws UnsupportedOperationException
194: * when removing from this Collection is not supported
195: */
196: public boolean remove(Object object) {
197: Iterator<?> it = iterator();
198: if (object != null) {
199: while (it.hasNext()) {
200: if (object.equals(it.next())) {
201: it.remove();
202: return true;
203: }
204: }
205: } else {
206: while (it.hasNext()) {
207: if (it.next() == null) {
208: it.remove();
209: return true;
210: }
211: }
212: }
213: return false;
214: }
215:
216: /**
217: * Removes all occurrences in this Collection of each object in the
218: * specified Collection. This operation traverses over the collection
219: * itself, to verify whether each element is contained in the specified
220: * collection. The object will be removed from the collection itself using
221: * the iterator's remove method if it is contained in the specified
222: * collection.
223: *
224: * This collection will throw an UnsupportedOperationException if the
225: * iterator returned does not implement remove method, and the element in
226: * the specified collection is contained in this collection.
227: *
228: * @param collection
229: * the Collection of objects to remove
230: * @return true if this Collection is modified, false otherwise
231: *
232: * @throws UnsupportedOperationException
233: * when removing from this Collection is not supported
234: * @throws NullPointerException
235: * if null is used to invoke this method
236: */
237: public boolean removeAll(Collection<?> collection) {
238: boolean result = false;
239: Iterator<?> it = iterator();
240: while (it.hasNext()) {
241: if (collection.contains(it.next())) {
242: it.remove();
243: result = true;
244: }
245: }
246: return result;
247: }
248:
249: /**
250: * Removes all objects from this Collection that are not contained in the
251: * specified Collection. This operation traverses over the collection
252: * itself, to verify whether any element is contained in the specified
253: * collection. The object will be removed from the collection itself using
254: * the iterator's remove method if it is not contained in the specified
255: * collection.
256: *
257: * This collection will throw an UnsupportedOperationException if the
258: * iterator returned does not implement remove method, and the collection
259: * itself does contain elements which do not exist in the specified
260: * collection.
261: *
262: * @param collection
263: * the Collection of objects to retain
264: * @return true if this Collection is modified, false otherwise
265: *
266: * @throws UnsupportedOperationException
267: * when removing from this Collection is not supported
268: * @throws NullPointerException
269: * if null is used to invoke this method
270: */
271: public boolean retainAll(Collection<?> collection) {
272: boolean result = false;
273: Iterator<?> it = iterator();
274: while (it.hasNext()) {
275: if (!collection.contains(it.next())) {
276: it.remove();
277: result = true;
278: }
279: }
280: return result;
281: }
282:
283: /**
284: * Answers the number of elements in this Collection.
285: *
286: * @return the number of elements in this Collection
287: */
288: public abstract int size();
289:
290: /**
291: * Answers a new array containing all elements contained in this Collection.
292: * All the elements in the array will not be referenced by the collection.
293: * The elements in the returned array will be sorted to the same order as
294: * those returned by the iterator of this collection itself if the
295: * collection guarantees the order.
296: *
297: * @return an array of the elements from this Collection
298: */
299: public Object[] toArray() {
300: int size = size(), index = 0;
301: Iterator<?> it = iterator();
302: Object[] array = new Object[size];
303: while (index < size) {
304: array[index++] = it.next();
305: }
306: return array;
307: }
308:
309: /**
310: * Answers an array containing all elements contained in this Collection. If
311: * the specified array is large enough to hold the elements, the specified
312: * array is used, otherwise an array of the same type is created. If the
313: * specified array is used and is larger than this Collection, the array
314: * element following the collection elements is set to null.
315: *
316: * @param contents
317: * the array
318: * @return an array of the elements from this Collection
319: *
320: * @throws ArrayStoreException
321: * when the type of an element in this Collection cannot be
322: * stored in the type of the specified array
323: * @throws NullPointerException
324: * if null is used to invoke this method
325: */
326: @SuppressWarnings("unchecked")
327: public <T> T[] toArray(T[] contents) {
328: int size = size(), index = 0;
329: if (size > contents.length) {
330: Class<?> ct = contents.getClass().getComponentType();
331: contents = (T[]) Array.newInstance(ct, size);
332: }
333: for (E entry : this ) {
334: contents[index++] = (T) entry;
335: }
336: if (index < contents.length) {
337: contents[index] = null;
338: }
339: return contents;
340: }
341:
342: /**
343: * Answers the string representation of this Collection. The presentation
344: * has a specific format. It is enclosed by square brackets ("[]"). Elements
345: * are separated by ', ' (comma and space).
346: *
347: * @return the string representation of this Collection
348: */
349: @Override
350: public String toString() {
351: if (isEmpty()) {
352: return "[]"; //$NON-NLS-1$
353: }
354:
355: StringBuilder buffer = new StringBuilder(size() * 16);
356: buffer.append('[');
357: Iterator<?> it = iterator();
358: while (it.hasNext()) {
359: Object next = it.next();
360: if (next != this ) {
361: buffer.append(next);
362: } else {
363: buffer.append("(this Collection)"); //$NON-NLS-1$
364: }
365: if (it.hasNext()) {
366: buffer.append(", "); //$NON-NLS-1$
367: }
368: }
369: buffer.append(']');
370: return buffer.toString();
371: }
372: }
|