THE ARRAYCOLLECTION IMPLEMENTATION OF THE COLLECTION INTERFACE


In this lab, you will get to know a little more about the Collection interface and partially develop an array-based implementation of that interface.

The Collection Interface

As you saw in Chapter 1, an interface consists of constants and abstract methods. There are no fields and no defined methods. An interface is implemented in a class, which provides method definitions for the abstract methods in the interface.

The main purpose of having an interface is to ensure standardization in the classes that implement the interface: those classes must provide definitions for the (necessarily abstract) methods in the interface. This imposes a discipline on developers of classes that implement that interface. For example, the Java Collections Framework, part of the package java.util, includes a number of collection classes that implement the Collection interface. Each such class has an add method, a size method, and so on. The definition of these methods may vary from one implementation to another, but the method headings must be the same for all the implementations. So when we introduce a new class that implements the Collection interface , you will already know a lot about the class, namely, how to call any of those methods. Of course, each such class may define some new methods as well.

Before you go any further, invest a few minutes studying the file Collection.java in java.util.

Here is a little of that file:

package java.util;

public interface Collection
{
  /**
   *  Checks if the Collection is empty.
   * 
   *  @return a boolean indicating whether the Collection is empty or not.
   **/
  boolean isEmpty();
  
  
  /**
   *  Adds element to the Collection if it is not already a member.
   * 
   *  @param element -  a reference of type E that will be added if it is 
   *           not already a member of the Collection.
   * 
   *  @return a boolean indicating whether element has been added to
   *          this Collection.  
   **/
  public boolean add (E element); 
  
  
  /**
   *  Empties the ArrayCollection of all elements.
   **/
  void clear();
  
  
  /**
   *  Checks if the ArrayCollection contains a certain element.
   * 
   *  @param obj -  an Object that will be checked for.
   * 
   *  @return a boolean indicating whether the ArrayCollection contains 
   *          Object obj.
   **/
  public boolean contains (Object obj);
}

All of the methods are abstract. Any class that implements Collection may provide definitions for all of those methods. If the implementing class does not implement some method, then the implementing class must be declared abstract.

The contains (Object obj) method deserves some discussion. It is the user's responsibility to ensure that the equals method is defined for the class that includes both obj and the elements in the Collection. For example, if the elements are Strings, the String class defines an appropriate equals method so that, for example,

String s = "gentle";
 
s.equals ("gentle");

returns true, and

String s = "gentle";

s.equals ("gentle  ");

returns false because the argument has two spaces at the end.

The contains method works fine if the element class has an equals method that compares elements. If not, and the immediate superclass of the element class has an equals method, that version of equals is used in the comparison. Ultimately, if no lower superclass of the element class has an equals method, the Object class's equals method applies. Here is that method:

public boolean equals(Object obj) {
	return (this == obj);
}

This version of equals compares references, not objects! So in the above contains method, false would always be returned, even if there were a matching element. In general, make sure that your element class (or one of its superclasses) has an equals method that compares elements, not references.