The Java TM Tutorial

| Start of Tutorial > Start of Trail > Start of Lesson | Search

Trail: Collections
Lesson: Interfaces

## The Collection Interface

> A Collection represents a group of objects, known as its elements. The primary use of the `Collection` interface is to pass around collections of objects where maximum generality is desired. For example, by convention all general-purpose collection implementations (which typically implement some subinterface of `Collection` like `Set` or `List`) have a constructor that takes a `Collection` argument. This constructor initializes the new `Collection` to contain all of the elements in the specified `Collection`. This constructor allows the caller to create a `Collection` of a desired implementation type, initially containing all of the elements in any given `Collection`, whatever its subinterface or implementation type. Suppose you have a `Collection`, `c`, which may be a `List`, a `Set`, or some other kind of `Collection`. The following one-liner creates a new `ArrayList` (an implementation of the `List` interface), initially containing all of the elements in `c`:

> >     List l = new ArrayList(c);

> The `Collection` interface is shown below:

> >     public interface Collection {
> >         // Basic Operations
> >         int size();
> >         boolean isEmpty();
> >         boolean contains(Object element);
> >         boolean add(Object element);    // Optional
> >         boolean remove(Object element); // Optional
> >         Iterator iterator();

> >         // Bulk Operations
> >         boolean containsAll(Collection c);
> >         boolean addAll(Collection c);    // Optional
> >         boolean removeAll(Collection c); // Optional
> >         boolean retainAll(Collection c); // Optional
> >         void clear();                    // Optional

> >         // Array Operations
> >         Object[] toArray();
> >         Object[] toArray(Object a[]);
> >     }

> The interface does about what you'd expect, given that a `Collection` represents a group of objects. It has methods to tell you how many elements are in the collection (`size`, `isEmpty`), to check if a given object is in the collection (`contains`), to add and remove an element from the collection (`add`, `remove`), and to provide an iterator over the collection (`iterator`).

> The `add` method is defined generally enough so that it makes sense for collections that allow duplicates as well as those that don't. It guarantees that the `Collection` will contain the specified element after the call completes, and returns `true` if the `Collection` changes as a result of the call. Similarly, the `remove` method is defined to remove a single instance of the specified element from the `Collection`, assuming the `Collection` contains the element, and to return `true` if the `Collection` was modified as a result.

### Iterators

> The object returned by the `iterator` method deserves special mention. It is an Iterator, which is very similar to an Enumeration, but differs in two respects:
> - `Iterator` allows the caller to remove elements from the underlying collection during the iteration with well-defined semantics.
> - Method names have been improved.
> The first point is important: There was no safe way to remove elements from a collection while traversing it with an `Enumeration`. The semantics of this operation were ill-defined, and differed from implementation to implementation.

> The `Iterator` interface is shown below:

> >     public interface Iterator {
> >         boolean hasNext();
> >         Object next();
> >         void remove();    // Optional
> >     }

> The `hasNext` method is identical in function to `Enumeration.hasMoreElements`, and the `next` method is identical in function to `Enumeration.nextElement`. The `remove` method removes from the underlying `Collection` the last element that was returned by `next`. The `remove` method may be called only once per call to `next`, and throws an exception if this condition is violated. Note that `Iterator.remove` is the only safe way to modify a collection during iteration; the behavior is unspecified if the underlying collection is modified in any other way while the iteration is in progress.

> The following snippet shows you how to use an `Iterator` to filter a `Collection`, that is, to traverse the collection, removing every element that does not satisfy some condition:

> >     static void filter(Collection c) {
> >         for (Iterator i = c.iterator(); i.hasNext(); )
> >             if (!cond(i.next()))
> >                 i.remove();
> >     }

> Two things should be kept in mind when looking at this simple piece of code:
> - The code is polymorphic: it works for any `Collection` that supports element removal, regardless of implementation. That's how easy it is to write a polymorphic algorithm under the collections framework!
> - It would have been impossible to write this using `Enumeration` instead of `Iterator`, because there's no safe way to remove an element from a collection while traversing it with an `Enumeration`.

### Bulk Operations

> The bulk operations perform some operation on an entire `Collection` in a single shot. They are shorthands in the sense that each of them can be simulated, perhaps less efficiently, using the operations described above.
> - `containsAll`: Returns `true` if the target `Collection` contains all of the elements in the specified `Collection` (`c`).
> - `addAll`: Adds all of the elements in the specified `Collection` to the target `Collection`.
> - `removeAll`: Removes from the target `Collection` all of its elements that are also contained in the specified `Collection`.
> - `retainAll`: Removes from the target `Collection` all of its elements that are not also contained in the specified `Collection`. That is to say, it retains only those elements in the target `Collection` that are also contained in the specified `Collection`.
> - `clear`: Removes all elements from the `Collection`.
> The `addAll`, `removeAll`, and `retainAll` methods all return `true` if the target `Collection` was modified in the process of executing the operation.

> As a simple example of the power of the bulk operations, consider following idiom to remove all instances of a specified element, `e` from a `Collection`, `c`.:

> >     c.removeAll(Collections.singleton(e));

> More specifically, suppose that you want to remove all of the null elements from a `Collection`:

> >     c.removeAll(Collections.singleton(null));

> This idiom uses `Collections.singleton`, which is a static factory method that returns an immutable `Set` containing only the specified element.

### Array Operations

> The `toArray` methods are provided as a bridge between collections and older APIs that expect arrays on input. They allow the contents of a `Collection` to be translated into an array. The simple form with no arguments creates a new array of `Object`. The more complex form allows the caller to provide an array or to choose the runtime type of the output array.

> For example, suppose `c` is a `Collection` The following snippet dumps the contents of `c` into a newly allocated array of `Object` whose length is identical to the number of elements in `c`:

> >     Object[] a = c.toArray();

> Suppose `c` is known to contain only strings. The following snippet dumps the contents of `c` into a newly allocated array of `String` whose length is identical to the number of elements in `c`:

> >     String[] a = (String[]) c.toArray(new String[0]);

| Start of Tutorial > Start of Trail | Search