/*
* @(#)AbstractCollection.java 1.11 98/09/30
*
* Copyright 1997, 1998 by Sun Microsystems, Inc.,
* 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Sun Microsystems, Inc. ("Confidential Information"). You
* shall not disclose such Confidential Information and shall use
* it only in accordance with the terms of the license agreement
* you entered into with Sun.
*/
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.
*
* @author Josh Bloch
* @version 1.11 09/30/98
* @see Collection
* @since JDK1.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();
/**
* Returns the number of elements in this collection. If the collection
* contains more than Integer.MAX_VALUE elements, returns
* Integer.MAX_VALUE.
*
* @return the number of elements in this collection.
*/
public abstract int size();
/**
* Returns true if this collection contains no elements.
*
* This implementation returns size() == 0.
*
* @return true if this collection contains no elements.
*/
public boolean isEmpty() {
return size() == 0;
}
/**
* Returns true if this collection contains the specified
* element. More formally, returns true if and only if this
* collection contains at least one element e such that
* (o==null ? e==null : o.equals(e)).
*
* 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 true if this collection contains the specified element.
*/
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;
}
/**
* 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.
*
* 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 = iterator();
for (int i=0; e.hasNext(); i++)
result[i] = e.next();
return result;
}
/**
* Returns an array with a runtime type is that of the specified array and
* that contains all of the elements in this collection. 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.
*
* 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
* null. This is useful in determining the length of the
* collection only if the caller knows that the collection does
* not contain any null elements.)
*
* 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.
*
* 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.
*
* @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 null.
*
* @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 Object[] toArray(Object a[]) {
int size = size();
if (a.length < size)
a = (Object[])java.lang.reflect.Array.newInstance(
a.getClass().getComponentType(), size);
Iterator it=iterator();
for (int i=0; i size)
a[size] = null;
return a;
}
// Modification Operations
/**
* Ensures that this collection contains the specified element (optional
* operation). Returns true if the collection changed as a
* result of the call. (Returns false 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 null 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.
*
* This implementation always throws an
* UnsupportedOperationException.
*
* @param o element whose presence in this collection is to be ensured.
* @return true if the collection changed as a result of the call.
*
* @throws UnsupportedOperationException if the add method is not
* supported by this collection.
*
* @throws NullPointerException if this collection does not permit
* null elements, and the specified element is
* null.
*
* @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(Object 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 e such that (o==null ? e==null :
* o.equals(e)), if the collection contains one or more such
* elements. Returns true if the collection contained the
* specified element (or equivalently, if the collection changed as a
* result of the call).
*
* 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.
*
* @param o element to be removed from this collection, if present.
* @return true if the collection contained the specified
* element.
*
* @throws UnsupportedOperationException if the remove method is
* not supported by this collection.
*/
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
/**
* Returns true if this collection contains all of the elements
* in the specified collection.
*
* 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.
*
* @param c collection to be checked for containment in this collection.
* @return true if this collection contains all of the elements
* in the specified collection.
*
* @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.)
*
* 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.
*
* @param c collection whose elements are to be added to this collection.
* @return true if this collection changed as a result of the
* call.
* @throws UnsupportedOperationException if the addAll method is
* not supported by this collection.
*
* @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;
}
/**
* Removes from this collection all of its elements that are contained in
* the specified collection (optional operation).
*
* 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.
*
* @param c elements to be removed from this collection.
* @return true if this collection changed as a result of the
* call.
*
* @throws UnsupportedOperationException removeAll is not supported
* by this collection.
*
* @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.
*
* 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.
*
* @return true if this collection changed as a result of the
* call.
*
* @throws UnsupportedOperationException if the retainAll method
* is not supported by this collection.
*
* @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;
}
/**
* Removes all of the elements from this collection (optional operation).
* The collection will be empty after this call returns (unless it throws
* an exception).
*
* 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.
*
* @throws UnsupportedOperationException if the remove method is
* not supported by this collection.
*/
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 String.valueOf(Object).
*
* 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 ", " 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();
Iterator e = iterator();
buf.append("[");
int maxIndex = size() - 1;
for (int i = 0; i <= maxIndex; i++) {
buf.append(String.valueOf(e.next()));
if (i < maxIndex)
buf.append(", ");
}
buf.append("]");
return buf.toString();
}
}