Lesson 8.3 Object Arrays
Object Arrays and Vectors
This lesson will teach you how to create and use arrays that contain objects instead of those that contain primitive values. You'll also learn to work with an array-like class, Vector, that is especially designed to hold objects, and which automatically resizes itself as necessary, unlike the built-in arrays.
Object Arrays
You create an array of objects using exactly the same syntax you use to create an array of primitive types.
Here, for instance, is how you create an array of Button objects for a toolbar:
| Button[] toolBar = new Button[5]; |
Up to this point, objects and primitive arrays work just the same. Now, however, the two diverge.
If toolBar were an array of double or int, each element would automatically be initialized to 0, so you could use the array immediately. With object arrays, however, each element is initialized to the special value null.
The value null is not very useful in its own right. Actually, its not useful at all. Before you can use toolBar, you have to fill each element with a valid Button reference by using the new operator on each element in the array like this:
int len = toolBar.length;
for (int i=0; i < len; i++)
{
toolBar[i] = new Button(""+(i+1));
} |
Once you're finished, each element in the toolBar array points to a new Button object, as the illustration shows.
[click on the image above to enlarge].
As you can see, every object array requires three steps to be useful:
- Declare an array variable.
- Create the array object.
- Create objects for each element in the array.

The ToolBar Example
Here's a little longer example you can study to make sure you understand how to create and use arrays of objects. Rather than showing you the entire listing for ToolBar.java, we'll just look at a few snippets. To view the entire listing, just click the link.
The init() Method
The init() method of Toolbar.java shows how to create a series of Button for a Button[] array, using a loop and a second array of Strings for the Button captions.
Inside the loop, these three things occur for each element of the Button[] array toolBar:
- Each element in the String array, captions, is passed as an argument to the Button constructor creating the Button objects for the toolBar array.
- Each toolBar element is attached to an ActionListener as it is created.
- A Panel object, here named p, is used to keep all of the Button objects together visibly. Inside the loop, each Button object is added to the Panel as it is created.
|
ToolBar.java init() Method
|
public void init()
{
// 1. Toolbar Panel
Panel p = new Panel();
p.setLayout(new FlowLayout(FlowLayout.LEFT));
p.setBackground(Color.lightGray);
// 2. Create the toolBar Buttons
String[] captions =
{ "Red", "Blue", "Green",
"Yellow", "Black" };
for (int i=0; i < toolBar.length; i++)
{
toolBar[i] = new Button(captions[i]);
toolBar[i].addActionListener(this);
p.add(toolBar[i]);
}
// 3. Add the Panel to the applet
setLayout(new BorderLayout());
add(p, "North");
} |
The actionPerformed() Method
Since each Button object is attached to the same ActionListener in the init() method, you have to find a way to tell which Button was clicked.
Fortunately, using an array of objects makes that quite easy. Using individual objects, instead of an array, you'd have to use an if-else-if-else structure. With an array, you can use a for loop like this:
- Retrieve the Object that generated the event. In Java 1.0 you'd use the Event.target field; in Java 1.1, you call the ActionEvent getSource() method.
- Create an int variable--here I've named it clicked--outside of your for loop. It's important that you don't create this variable in the initializer section of your for loop because you need to reference it after the loop terminates.
- Write a for loop that steps through each element in your toolBar array, and compares the element to the Object that generated the event. When you locate the correct object, simply break out of the loop.
- Now, you have an int variable you can use in a switch statement to take the appropriate action.
Here's the entire actionPerformed() method:
|
ToolBar.java actionPerformed() Method
|
public void actionPerformed(ActionEvent ae)
{
// 1. Retrieve source of click
Object obj = ae.getSource();
// 2. Match it with toolBar Button
int clicked;
for (clicked = 0;
clicked < toolBar.length; clicked++)
{
if (obj == toolBar[clicked])
break;
}
// 3. Take action based on Button pressed
switch (clicked)
{
case 0: setBackground(Color.red);
break;
case 1: setBackground(Color.blue);
break;
case 2: setBackground(Color.green);
break;
case 3: setBackground(Color.yellow);
break;
case 4: setBackground(Color.black);
break;
}
repaint();
}
ToolBar.java creates an array of Buttons. Press one of the Buttons to change the background color of the applet.
|
The Vector Class
One of the problems with using arrays, is that they are fixed-size. If you plan for ten elements when you create your array, you can't change your mind after the program is running, and add an eleventh element.
A Vector, however, lets you do just that. A Vector is a resizable array that can only hold objects. If you want to store primitive types in a Vector, you have to "wrap" each primitive value up in one of Java's wrapper classes [Integer, Double, etc.]. When you add an eleventh element to a ten-element Vector, the Vector will automatically resize.
Vector Basics
Let's look at the various steps you follow to use a Vector. Then, when you're finished, we'll revisit ToolBar.java, using a Vector to make it a little more flexible. The Vector class is in the java.util package, so you have to remember to add
to any programs that use Vectors, just as when using the Date or Random classes.
Creating a Vector
Since Vector is a class, and not a built-in language feature like arrays, you use a regular constructor to create a Vector object. Here are some examples:
Vector v1 = new Vector();
Vector v2 = new Vector(100);
Vector v3 = new Vector(100, 25); |
When you create a Vector using the default constructor, like the Vector v1 in this example, it can initially hold 10 elements. This is called the Vector's capacity. If you like, you can supply an initial capacity as Vector v2 does.
Once v1 holds 10 elements, or v2 holds 100 elements, adding an additional element causes the Vector to grow. Both v1 and v2 will grow by doubling their capacity. After adding an 11th element to v1, its new capacity will be 20. After adding a 101st element to v2, its new capacity will be 200.
If this strategy of doubling each time a Vector grows causes problems, you may specify a third constructor used for the Vector v3. This constructor allows you to supply both an initial capacity as well as a growth factor. Each time the Vector v3 grows, it will simply increase by 25 elements, no matter how large it gets.
Adding Elements
You can add objects to a Vector using one of two methods. Here's an example that shows both methods using two Button objects, named one and zero.
Button one = new Button("One");
Button zero = new Button("Zero");
v1.addElement(one);
v1.insertElementAt(zero, 0); |
The addElement() method adds the new element to the end of the Vector. Vectors are indexed, just like arrays, starting at zero. After adding the Button one to the Vector v1, the Button one is in position 0.
The second method for adding elements to a Vector, insertElementAt(), allows you to specify which position the new element should occupy. When you use insertElementAt() the new element does not replace what was previously at that location. Instead, all of the elements in the Vector are shifted "up" one to make room for the new arrival. After inserting the Button zero at position 0, the Button one is moved to position 1.
Using Vector Elements
Arrays are easy to use because you can use simple assignment to replace or retrieve the value stored in a particular element. You can't do that with the Vector class. Instead, you have to use one method to replace an element:
| setElementAt(Object o, int index); |
and another to retrieve the element:
Also, because Vectors really hold Object references and not Button or Label references, you have to cast the Object reference you retrieve to the correct type to use it.
Although storing and retrieving objects in a Vector is more work than using an array, many common operations that you have to perform "by hand" when using arrays are automatic when using Vectors.
For instance, to find out if a particular object is contained in a Vector, you can use the contains() method. If you already know that a particular object is located in a Vector, you can retrieve its position using indexOf(). You can remove an object from a Vector using removeElementAt(). When you do this, the other objects move "down" to close up the gap left by the departee.
The ToolBarV Example
Here as promised is ToolBar.java converted so that it uses a Vector instead of an array. The most important changes in ToolBarV.java:
Something to Talk About
Let's try working with object arrays. See if you can write a fragment of code that does this:
- Define and initialize an object array called titles that contains 7 Label objects.
- Use a separate String array to hold the text that you would like to appear on the Labels.
Please continue to the next section of this lesson.
|