Lecture week 19 - Collection classes in Java

It is frequently required in programs to deal with large numbers of similar things, e.g. :- As it is difficult and inconvenient to have to give each data item its own variable name, the whole collection is given a name and the items within the collection referred to by a subscript or some other key value.

JDK1.1 provides three main collection classes as follows :-

Type compatibility extensions

Before considering Vectors, there is an important issue to raise concerning type compatibility.

As you will remember Java is a strongly typed language - that is, you are not allowed to mix types in expressions or when making assignments, e.g.

int j = 10; float x = 23.4; j = x; //illegal as the 0.4 will be lost leaving 23 x = j; //legal as no information is lost j = (int)x; //legal as programmer instructs computer to do it Paper p = new Paper(); Turtle t = new Turtle(p); p = t; //illegal as a Turtle is a different type to Paper From this you will see that with built-in types - byter, short, int, long, float, double, char, boolean conversion is only automatic if no information is lost, otherwise it must be explicitly requested with a cast such as (int).

In the case of variables referencing objects, the situation isdifferent. Any variable of a particular class can be assigned a variable of the same class OR ANY SUB CLASS. Hence the following is legal :-

Paper pad = new Paper(); Turtle t; GraphicsTurtle g = new GraphicsTurtle(pad); t = g; //legal as g is a sub-class of t g = t; //illegal as t is a super-class of g This ability to assign a sub-class to a super-class variable also applies to method parameters, e.g. given a method :- public void demoMethod(Turtle t) { //code to manipulate a Turtle } another program can call this method, passing it not only a Turtle instance but also any object which is a sub-class of Turtle, e.g. :- Paper p = new Paper(); GraphicsTurtle gt = new GraphicsTurtle(p); someObject.demoMethod(gt); //pass a GraphicsTurtle instead of a Turtle This turns out to be a very powerful feature of object-oriented languages.

Making collection classes more useful

Collection classes like Vectors when defined have to be declared as being collections of some kind of object. In the case of Vectors this is predefined as instances of the class Object.

The above rule governing type compatibility will allow us to place into a collection any instance of the class Object or any of its sub-classes.

As all classes are sub-classes of Object this means a collection can contain ANY class of object at all - and at the same time if desired.

The need for wrapper classes

Note in the above description, a Vector may contain any class of object - the problem with this is that if we want to store simple ints for example we cant. They are not objects (i.e. they do not belong to a class which is a sub-class of Object).

The problem is solved by the provision in Java of what are called wrapper classes. If you want to store ints in a Vector then you must create an instance of the class Integer which contains the int as an attribute and then this can be placed in a Vector. The int value can later be retrieved from inside the Integer instance object.

Wrapper classes exist for all the main categories of built-in types - Integer, Float, Character, Boolean.

The need for downcasting

One problem of using Vectors is that, because Java thinks that a Vector is a collection of Object class instances, when you retrieve an item from the collection, the compiler assumes that it is an instance of the class Object.

If you know that it is actually a Turtle instance and want to draw with it by sending messages like penDown() and moveTo() the compiler will object because these methods are not defined for instances of the class Object.

In order to allow these messages, or for that matter the assignment of the item to a reference of class Turtle you have to supply a cast to inform the compiler that the item being retrieved really is a Turtle.

This is done like this :-

Turtle t; Vector v = new Vector(); //code to put various things into the Vector v t = (Turtle)v.elementAt(3); //access the fourth item in the vector //and assign it to the variable t //inform the compiler that it is a Turtle t.penDown(); //send it messages as usual //other commands to draw whatever The process of casting from the presumed class - Object to a sub-class Turtle is called downcasting. This is a dangerous process as it relies on our knowledge of what the vector contains. If the fourth item was not actually a Turtle but say an Integer the messages subsequently sent like penDown() would be meaningless and would cause the program to crash.

Vectors in Java

The Vector class in Java provides an extensible array of any kind of object and supports a number of powerful methods such as :-