/* * @(#)AbstractCollection.java 1.31 03/12/19 * * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package tests.java15.util; import java.util.Collection; import java.util.Iterator; /** * This class provides a skeletal implementation of the <tt>Collection</tt> * interface, to minimize the effort required to implement this interface. <p> * * To implement an unmodifiable collection, the programmer needs only to * extend this class and provide implementations for the <tt>iterator</tt> and * <tt>size</tt> methods. (The iterator returned by the <tt>iterator</tt> * method must implement <tt>hasNext</tt> and <tt>next</tt>.)<p> * * To implement a modifiable collection, the programmer must additionally * override this class's <tt>add</tt> method (which otherwise throws an * <tt>UnsupportedOperationException</tt>), and the iterator returned by the * <tt>iterator</tt> method must additionally implement its <tt>remove</tt> * method.<p> * * The programmer should generally provide a void (no argument) and * <tt>Collection</tt> constructor, as per the recommendation in the * <tt>Collection</tt> interface specification.<p> * * 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.<p> * * This class is a member of the * <a href="{@docRoot}/../guide/collections/index.html"> * Java Collections Framework</a>. * * @author Josh Bloch * @author Neal Gafter * @version 1.24, 01/18/03 * @see Collection * @since 1.2 */ public abstract class AbstractCollection<E> implements Collection<E> { /** * 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<E> iterator(); /** * Returns the number of elements in this collection. If the collection * contains more than <tt>Integer.MAX_VALUE</tt> elements, returns * <tt>Integer.MAX_VALUE</tt>. * * @return the number of elements in this collection. */ public abstract int size(); /** * Returns <tt>true</tt> if this collection contains no elements.<p> * * This implementation returns <tt>size() == 0</tt>. * * @return <tt>true</tt> if this collection contains no elements. */ public boolean isEmpty() { return size() == 0; } /** * Returns <tt>true</tt> if this collection contains the specified * element. More formally, returns <tt>true</tt> if and only if this * collection contains at least one element <tt>e</tt> such that * <tt>(o==null ? e==null : o.equals(e))</tt>.<p> * * This implementation iterates over the elements in the collection, * checking each element in turn for equality with the specified element. * * @param o object to be checked for containment in this collection. * @return <tt>true</tt> if this collection contains the specified element. */ public boolean contains(Object o) { Iterator<E> 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; } /** * Returns an array containing all of the elements in this collection. If * the collection makes any guarantees as to what order its elements are * returned by its iterator, this method must return the elements in the * same order. The returned array will be "safe" in that no references to * it are maintained by the collection. (In other words, this method must * allocate a new array even if the collection is backed by an Array). * The caller is thus free to modify the returned array.<p> * * 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. * * @return an array containing all of the elements in this collection. */ public Object[] toArray() { Object[] result = new Object[size()]; Iterator<E> e = iterator(); for (int i=0; e.hasNext(); i++) result[i] = e.next(); return result; } /** * Returns an array containing all of the elements in this collection; * the runtime type of the returned array is that of the specified array. * If the collection fits in the specified array, it is returned therein. * Otherwise, a new array is allocated with the runtime type of the * specified array and the size of this collection.<p> * * If the collection fits in the specified array with room to spare (i.e., * the array has more elements than the collection), the element in the * array immediately following the end of the collection is set to * <tt>null</tt>. This is useful in determining the length of the * collection <i>only</i> if the caller knows that the collection does * not contain any <tt>null</tt> elements.)<p> * * If this collection makes any guarantees as to what order its elements * are returned by its iterator, this method must return the elements in * the same order. <p> * * 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 <tt>null</tt> is stored in the first location after the * end of the collection. * * @param a the array into which the elements of the collection are to * be stored, if it is big enough; otherwise, a new array of the * same runtime type is allocated for this purpose. * @return an array containing the elements of the collection. * * @throws NullPointerException if the specified array is <tt>null</tt>. * * @throws ArrayStoreException if the runtime type of the specified array * is not a supertype of the runtime type of every element in this * collection. */ public <T> T[] toArray(T[] a) { int size = size(); if (a.length < size) a = (T[])java.lang.reflect.Array .newInstance(a.getClass().getComponentType(), size); Iterator<E> it=iterator(); Object[] result = a; for (int i=0; i<size; i++) result[i] = it.next(); if (a.length > size) a[size] = null; return a; } // Modification Operations /** * Ensures that this collection contains the specified element (optional * operation). Returns <tt>true</tt> if the collection changed as a * result of the call. (Returns <tt>false</tt> if this collection does * not permit duplicates and already contains the specified element.) * Collections that support this operation may place limitations on what * elements may be added to the collection. In particular, some * collections will refuse to add <tt>null</tt> elements, and others will * impose restrictions on the type of elements that may be added. * Collection classes should clearly specify in their documentation any * restrictions on what elements may be added.<p> * * This implementation always throws an * <tt>UnsupportedOperationException</tt>. * * @param o element whose presence in this collection is to be ensured. * @return <tt>true</tt> if the collection changed as a result of the call. * * @throws UnsupportedOperationException if the <tt>add</tt> method is not * supported by this collection. * * @throws NullPointerException if this collection does not permit * <tt>null</tt> elements, and the specified element is * <tt>null</tt>. * * @throws ClassCastException if the class of the specified element * prevents it from being added to this collection. * * @throws IllegalArgumentException if some aspect of this element * prevents it from being added to this collection. */ public boolean add(E o) { throw new UnsupportedOperationException(); } /** * Removes a single instance of the specified element from this * collection, if it is present (optional operation). More formally, * removes an element <tt>e</tt> such that <tt>(o==null ? e==null : * o.equals(e))</tt>, if the collection contains one or more such * elements. Returns <tt>true</tt> if the collection contained the * specified element (or equivalently, if the collection changed as a * result of the call).<p> * * 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.<p> * * Note that this implementation throws an * <tt>UnsupportedOperationException</tt> if the iterator returned by this * collection's iterator method does not implement the <tt>remove</tt> * method and this collection contains the specified object. * * @param o element to be removed from this collection, if present. * @return <tt>true</tt> if the collection contained the specified * element. * @throws UnsupportedOperationException if the <tt>remove</tt> method is * not supported by this collection. */ public boolean remove(Object o) { Iterator<E> 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 /** * Returns <tt>true</tt> if this collection contains all of the elements * in the specified collection. <p> * * 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 * <tt>true</tt> is returned, otherwise <tt>false</tt>. * * @param c collection to be checked for containment in this collection. * @return <tt>true</tt> if this collection contains all of the elements * in the specified collection. * @throws NullPointerException if the specified collection is null. * * @see #contains(Object) */ public boolean containsAll(Collection<?> c) { Iterator<?> e = c.iterator(); while (e.hasNext()) if(!contains(e.next())) return false; return true; } /** * Adds all of the elements in the specified collection to this collection * (optional operation). The behavior of this operation is undefined if * the specified collection is modified while the operation is in * progress. (This implies that the behavior of this call is undefined if * the specified collection is this collection, and this collection is * nonempty.) <p> * * This implementation iterates over the specified collection, and adds * each object returned by the iterator to this collection, in turn.<p> * * Note that this implementation will throw an * <tt>UnsupportedOperationException</tt> unless <tt>add</tt> is * overridden (assuming the specified collection is non-empty). * * @param c collection whose elements are to be added to this collection. * @return <tt>true</tt> if this collection changed as a result of the * call. * @throws UnsupportedOperationException if this collection does not * support the <tt>addAll</tt> method. * @throws NullPointerException if the specified collection is null. * * @see #add(Object) */ public boolean addAll(Collection<? extends E> c) { boolean modified = false; Iterator<? extends E> e = c.iterator(); while (e.hasNext()) { if (add(e.next())) modified = true; } return modified; } /** * Removes from this collection all of its elements that are contained in * the specified collection (optional operation). <p> * * 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 <tt>remove</tt> method.<p> * * Note that this implementation will throw an * <tt>UnsupportedOperationException</tt> if the iterator returned by the * <tt>iterator</tt> method does not implement the <tt>remove</tt> method * and this collection contains one or more elements in common with the * specified collection. * * @param c elements to be removed from this collection. * @return <tt>true</tt> if this collection changed as a result of the * call. * @throws UnsupportedOperationException if the <tt>removeAll</tt> method * is not supported by this collection. * @throws NullPointerException if the specified collection is null. * * @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; } /** * Retains only the elements in this collection that are contained in the * specified collection (optional operation). In other words, removes * from this collection all of its elements that are not contained in the * specified collection. <p> * * 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 <tt>remove</tt> method.<p> * * Note that this implementation will throw an * <tt>UnsupportedOperationException</tt> if the iterator returned by the * <tt>iterator</tt> method does not implement the <tt>remove</tt> method * and this collection contains one or more elements not present in the * specified collection. * * @param c elements to be retained in this collection. * @return <tt>true</tt> if this collection changed as a result of the * call. * @throws UnsupportedOperationException if the <tt>retainAll</tt> method * is not supported by this Collection. * @throws NullPointerException if the specified collection is null. * * @see #remove(Object) * @see #contains(Object) */ public boolean retainAll(Collection<?> c) { boolean modified = false; Iterator<E> e = iterator(); while (e.hasNext()) { if (!c.contains(e.next())) { e.remove(); modified = true; } } return modified; } /** * Removes all of the elements from this collection (optional operation). * The collection will be empty after this call returns (unless it throws * an exception).<p> * * This implementation iterates over this collection, removing each * element using the <tt>Iterator.remove</tt> operation. Most * implementations will probably choose to override this method for * efficiency.<p> * * Note that this implementation will throw an * <tt>UnsupportedOperationException</tt> if the iterator returned by this * collection's <tt>iterator</tt> method does not implement the * <tt>remove</tt> method and this collection is non-empty. * * @throws UnsupportedOperationException if the <tt>clear</tt> method is * not supported by this collection. */ public void clear() { Iterator<E> 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 * (<tt>"[]"</tt>). Adjacent elements are separated by the characters * <tt>", "</tt> (comma and space). Elements are converted to strings as * by <tt>String.valueOf(Object)</tt>.<p> * * This implementation creates an empty string buffer, appends a left * square bracket, and iterates over the collection appending the string * representation of each element in turn. After appending each element * except the last, the string <tt>", "</tt> is appended. Finally a right * bracket is appended. A string is obtained from the string buffer, and * returned. * * @return a string representation of this collection. */ public String toString() { StringBuffer buf = new StringBuffer(); buf.append("["); Iterator<E> i = iterator(); boolean hasNext = i.hasNext(); while (hasNext) { E o = i.next(); buf.append(o == this ? "(this Collection)" : String.valueOf(o)); hasNext = i.hasNext(); if (hasNext) buf.append(", "); } buf.append("]"); return buf.toString(); } }