/* * %W% %E% * * Copyright 2005 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.util; /** * This class provides a skeletal implementation of the Collection * interface, to minimize the effort required to implement this interface.

* * To implement an unmodifiable collection, the programmer needs only to * extend this class and provide implementations for the iterator and * size methods. (The iterator returned by the iterator * method must implement hasNext and next.)

* * To implement a modifiable collection, the programmer must additionally * override this class's add method (which otherwise throws an * UnsupportedOperationException), and the iterator returned by the * iterator method must additionally implement its remove * method.

* * The programmer should generally provide a void (no argument) and * Collection constructor, as per the recommendation in the * Collection interface specification.

* * The documentation for each non-abstract methods in this class describes its * implementation in detail. Each of these methods may be overridden if * the collection being implemented admits a more efficient implementation.

* * This class is a member of the * * Java Collections Framework. * * @author Josh Bloch * @author Neal Gafter * @version 1.24, 01/18/03 * @see Collection * @since 1.2 */ public abstract class AbstractCollection implements Collection { /** * Sole constructor. (For invocation by subclass constructors, typically * implicit.) */ protected AbstractCollection() { } // Query Operations /** * Returns an iterator over the elements contained in this collection. * * @return an iterator over the elements contained in this collection */ public abstract Iterator iterator(); public abstract int size(); /** * {@inheritDoc} * *

This implementation returns size() == 0. */ public boolean isEmpty() { return size() == 0; } /** * {@inheritDoc} * *

This implementation iterates over the elements in the collection, * checking each element in turn for equality with the specified element. * * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public boolean contains(Object o) { Iterator e = iterator(); if (o==null) { while (e.hasNext()) if (e.next()==null) return true; } else { while (e.hasNext()) if (o.equals(e.next())) return true; } return false; } /** * {@inheritDoc} * *

This implementation allocates the array to be returned, and iterates * over the elements in the collection, storing each object reference in * the next consecutive element of the array, starting with element 0. */ public Object[] toArray() { // Estimate size of array; be prepared to see more or fewer elements Object[] r = new Object[size()]; int i = 0; Iterator it = iterator(); while (i < r.length && it.hasNext()) r[i++] = it.next(); // Trim if overallocated; expand if underallocated if (i < r.length || it.hasNext()) return resizeAndFinishToArray(r, i, it); return r; } /** * {@inheritDoc} * *

This implementation checks if the array is large enough to contain the * collection; if not, it allocates a new array of the correct size and * type (using reflection). Then, it iterates over the collection, * storing each object reference in the next consecutive element of the * array, starting with element 0. If the array is larger than the * collection, a null is stored in the first location after the * end of the collection. * * @throws ArrayStoreException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public T[] toArray(T[] a) { // Estimate size of array; be prepared to see more or fewer elements int size = size(); T[] r = a.length >= size ? a : (T[])java.lang.reflect.Array .newInstance(a.getClass().getComponentType(), size); int i = 0; Iterator it = iterator(); while (i < r.length && it.hasNext()) r[i++] = (T)it.next(); // Trim if overallocated; expand if underallocated if (it.hasNext() || (r != a && i < r.length)) return resizeAndFinishToArray(r, i, it); if (i < r.length) r[i] = null; // null-terminate if provided array is too big return r; } /** * Reallocates the array being used within toArray that has a * different number of elements than expected, and finishes * filling it from the given iterator, if necessary. * * @param r the array * @param i the next array index to fill * @param it the in-progress iterator over the collection * @return array containing the elements in the given array, plus any * further elements returned by the iterator, trimmed to size */ private static T[] resizeAndFinishToArray(T[] r, int i, Iterator it) { while (it.hasNext()) { int cap = r.length; if (i < cap) r[i++] = (T)it.next(); else if (cap < Integer.MAX_VALUE) { // expand int newCap = (cap * 3) / 2 + 1; if (newCap <= cap) // integer overflow newCap = Integer.MAX_VALUE; r = Arrays.copyOf(r, newCap); } else // can't expand throw new OutOfMemoryError("Required array size too large"); } // trim if overallocated return i == r.length ? r : Arrays.copyOf(r, i); } // Modification Operations /** * {@inheritDoc} * *

This implementation always throws an * UnsupportedOperationException. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} */ public boolean add(E e) { throw new UnsupportedOperationException(); } /** * {@inheritDoc} * *

This implementation iterates over the collection looking for the * specified element. If it finds the element, it removes the element * from the collection using the iterator's remove method. * *

Note that this implementation throws an * UnsupportedOperationException if the iterator returned by this * collection's iterator method does not implement the remove * method and this collection contains the specified object. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} */ public boolean remove(Object o) { Iterator e = iterator(); if (o==null) { while (e.hasNext()) { if (e.next()==null) { e.remove(); return true; } } } else { while (e.hasNext()) { if (o.equals(e.next())) { e.remove(); return true; } } } return false; } // Bulk Operations /** * {@inheritDoc} * *

This implementation iterates over the specified collection, * checking each element returned by the iterator in turn to see * if it's contained in this collection. If all elements are so * contained true is returned, otherwise false. * * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @see #contains(Object) */ public boolean containsAll(Collection c) { Iterator e = c.iterator(); while (e.hasNext()) if (!contains(e.next())) return false; return true; } /** * {@inheritDoc} * *

This implementation iterates over the specified collection, and adds * each object returned by the iterator to this collection, in turn. * *

Note that this implementation will throw an * UnsupportedOperationException unless add is * overridden (assuming the specified collection is non-empty). * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * @throws IllegalArgumentException {@inheritDoc} * @throws IllegalStateException {@inheritDoc} * * @see #add(Object) */ public boolean addAll(Collection c) { boolean modified = false; Iterator e = c.iterator(); while (e.hasNext()) { if (add(e.next())) modified = true; } return modified; } /** * {@inheritDoc} * *

This implementation iterates over this collection, checking each * element returned by the iterator in turn to see if it's contained * in the specified collection. If it's so contained, it's removed from * this collection with the iterator's remove method. * *

Note that this implementation will throw an * UnsupportedOperationException if the iterator returned by the * iterator method does not implement the remove method * and this collection contains one or more elements in common with the * specified collection. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * * @see #remove(Object) * @see #contains(Object) */ public boolean removeAll(Collection c) { boolean modified = false; Iterator e = iterator(); while (e.hasNext()) { if (c.contains(e.next())) { e.remove(); modified = true; } } return modified; } /** * {@inheritDoc} * *

This implementation iterates over this collection, checking each * element returned by the iterator in turn to see if it's contained * in the specified collection. If it's not so contained, it's removed * from this collection with the iterator's remove method. * *

Note that this implementation will throw an * UnsupportedOperationException if the iterator returned by the * iterator method does not implement the remove method * and this collection contains one or more elements not present in the * specified collection. * * @throws UnsupportedOperationException {@inheritDoc} * @throws ClassCastException {@inheritDoc} * @throws NullPointerException {@inheritDoc} * * @see #remove(Object) * @see #contains(Object) */ public boolean retainAll(Collection c) { boolean modified = false; Iterator e = iterator(); while (e.hasNext()) { if (!c.contains(e.next())) { e.remove(); modified = true; } } return modified; } /** * {@inheritDoc} * *

This implementation iterates over this collection, removing each * element using the Iterator.remove operation. Most * implementations will probably choose to override this method for * efficiency. * *

Note that this implementation will throw an * UnsupportedOperationException if the iterator returned by this * collection's iterator method does not implement the * remove method and this collection is non-empty. * * @throws UnsupportedOperationException {@inheritDoc} */ public void clear() { Iterator e = iterator(); while (e.hasNext()) { e.next(); e.remove(); } } // String conversion /** * Returns a string representation of this collection. The string * representation consists of a list of the collection's elements in the * order they are returned by its iterator, enclosed in square brackets * ("[]"). Adjacent elements are separated by the characters * ", " (comma and space). Elements are converted to strings as * by {@link String#valueOf(Object)}. * * @return a string representation of this collection */ public String toString() { Iterator i = iterator(); if (! i.hasNext()) return "[]"; StringBuilder sb = new StringBuilder(); sb.append('['); for (;;) { E e = i.next(); sb.append(e == this ? "(this Collection)" : e); if (! i.hasNext()) return sb.append(']').toString(); sb.append(", "); } } }