JavaData & JavaData Structures in Java: Part 15, The toArray Method, Part 1

Data Structures in Java: Part 15, The toArray Method, Part 1

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Java Programming, Lecture Notes #1378


Preface


A miniseries

This lesson is part of a miniseries on Java data structures and the
Java Collections Framework.  The first lesson in the miniseries
was entitled
Data
Structures in Java: Part 1, Getting Started
.  The previous lesson
was entitled Data Structures in Java: Part 14, The
Comparator Interface, Part 6
.

The purpose of this miniseries is to help you learn the essential features
of Object-Oriented data structures in Java using the Collections Framework.

A sub-series

This is also the first lesson in a sub-series on the toArray
method.  The primary purpose of the lessons in this sub-series is
to teach you how to use the overloaded toArray method, which is
declared in the Collection interface.

Viewing tip

You may find it useful to open another copy of this lesson in a separate
browser window.  That will make it easier for you to scroll back and
forth among the different listings while you are reading about them.

Supplementary material

I recommend that you also study the other lessons in my extensive collection
of online Java tutorials.  You will find those lessons published at
Gamelan.com
However, as of the date of this writing, Gamelan doesn’t maintain a consolidated
index of my Java tutorial lessons, and sometimes they are difficult to
locate there.  You will find a consolidated index at
Baldwin’s
Java Programming Tutorials
.

Preview


In earlier lessons, I used the toArray method,
declared in the Collection interface, to copy elements from a collection
into an array.  However, in those lessons, I didn’t take the time
to fully explain how to use the method.  Also, I didn’t fully explain
the precautions that you need to take when you use the method.

The Collection interface declares the following
two overloaded versions of the toArray method:

public Object[] toArray()

public Object[] toArray(Object[] a)

In this lesson, will teach you how to use the
first (simpler) version of the toArray method.  I will
also show why you need to exercise care when using the elements stored
in the array to avoid corrupting the state of the objects referred to by
the elements in the collection.

I will teach you how to use the second (more
complex)
version of the toArray method in the next lesson.

Discussion
and Sample Program


Beginning with a quiz

Let’s begin with a little quiz to test your prior knowledge of the Collections
Framework.  To take this quiz, examine the program shown in Listing
1 and write down the output produced by the program.

 

//File ToArray01.java
//Copyright 2001, R.G.Baldwin
import java.util.*;
import javax.swing.*;

public class ToArray01{
  public static void main(
                        String args[]){
    new Worker().doIt();
  }//end main()
}//end class ToArray01
//===================================//

class Worker{
  public void doIt(){
    Collection ref;

    //Create, populate, and display the
    // contents of a collection
    ref = new LinkedList();
    Populator.fillIt(ref);
    System.out.println(
                "Collection contents");
    showCollection(ref);
    
    //Get collection contents into the
    // array and display the new
    // contents of the array.
    Object[] array = ref.toArray();
    System.out.println(
                 "New array contents");
    showArray(array);

    //Modify a property of an object
    // referred to by one of the
    // elements in the array. Display
    // array contents after 
    // modification
    System.out.println(
            "Modified array contents");
    ((JComponent)array[0]).
                  setToolTipText("XX");
    showArray(array);
    
    //Display the contents of the
    // collection
    System.out.println(
                "Collection contents");
    showCollection(ref);
  }//end doIt()
//-----------------------------------//
    
  //Utility method for displaying
  // array contents
  void showArray(Object[] array){
    for(int i = 0; i < array.length;
                                  i++){
      if(array[i] == null){
        System.out.print("null ");
      }else{
        System.out.print(
                ((JComponent)array[i]).
               getToolTipText() + " ");
      }//end else
    }//end for loop
    System.out.println();
  }//end showArray()
//-----------------------------------//

  //Utility method for displaying
  // collection contents
  void showCollection(Collection ref){
    Iterator iter = ref.iterator();
    while(iter.hasNext()){
      System.out.print(
             ((JComponent)iter.next()).
               getToolTipText() + " ");
    }//end while loop
    System.out.println();
  }//end showCollection
}// end class Worker
//===================================//

class Populator{
  public static void fillIt(
                       Collection ref){
    ref.add(new JButton());
    ref.add(new JButton());
    ref.add(new JLabel());
    ref.add(new JButton());
    ref.add(new JButton());
    ref.add(new JLabel());
    
    Iterator iter = ref.iterator();
    int cnt = 0;
    JComponent refVar;
    while(iter.hasNext()){
      refVar = (JComponent)iter.next();
      if(refVar instanceof JButton){
        refVar.setToolTipText(
                            "B"+cnt++);
      }else{
        refVar.setToolTipText(
                          "L" + cnt++);
      }//end else
    }//end while loop
    
  }//end fillIt()
}//end class Populator

Listing 1

And the answer is …

The correct answer to the quiz is the program output shown below:

Collection contents

B0 B1 L2 B3 B4 L5

New array contents

B0 B1 L2 B3 B4 L5

Modified array contents

XX B1 L2 B3 B4 L5

Collection contents

XX B1 L2 B3 B4 L5

If that was your answer, you probably already understand most of the
material covered in this lesson.  In that case, you might consider
skipping this lesson and moving on to the next lesson.  If that wasn’t
your answer, you should probably continue with your study of this lesson.

A new LinkedList collection

The code in Listing 2 creates and populates a new LinkedList
collection.  The collection is populated by passing the LinkedList
object’s reference to a method named fillIt.

The code in Listing 2 also displays the contents of the LinkedList
after it has been populated.  The list is displayed by passing the
LinkedList
object’s reference to a method named showCollection.

 

    Collection ref;
    ref = new LinkedList();

    Populator.fillIt(ref);

    System.out.println(
                "Collection contents");
    showCollection(ref);

Listing 2

The LinkedList class

The LinkedList class is one of the concrete class implementations
of the Collections Framework.  This class implements the Collection
interface and the List interface.  Thus, it adheres to the
contracts and stipulations of the List interface.

Here is part of what Sun has to say about this class:

“Linked list implementation of the List interface. Implements
all optional list operations, and permits all elements (including null).
In addition …”

Populating the LinkedList collection

The beginning of the static fillIt method, used to populate the
collection, is shown in Listing 3.

 

  public static void fillIt(
                       Collection ref){
    ref.add(new JButton());
    ref.add(new JButton());
    ref.add(new JLabel());
    ref.add(new JButton());
    ref.add(new JButton());
    ref.add(new JLabel());

Listing 3

As shown in Listing 3, the fillIt method begins by invoking the
add
method six times in succession, passing references to new anonymous objects
as a parameter to the add method.

Four buttons and two labels

Four of the objects are instantiated from the class named JButton
Two of the objects are instantiated from the class named JLabel.

Both JButton and JLabel belong to the javax.swing
package.  Further, both are subclasses of the class named JComponent.

The toolTipText property

Finally, both classes have a property named toolTipText, which
can be set and accessed by invoking the following methods on a reference
to the object:

void setToolTipText(String text)

String getToolTipText()

Why am I using Swing GUI components?

I really don’t plan to do anything special with these two Swing GUI
components.  Rather, I chose to use them for illustration purposes
simply because they possess the characteristics that I need for this lesson,
and the next lesson.  Those characteristics are:

  • Both classes subclass the class named JComponent (a common superclass
    below the Object class).
  • Both classes inherit a property (toolTipText) that can be used to
    identify them later.

Making the objects distinguishable

After the code in Listing 3 has been executed, the buttons and labels
are indistinguishable on the basis of the value of their toolTipText
property.

The code in Listing 4 deals with this issue.  This code uses the
setToolTipText
method to store a unique String value in the
toolTipText
property of the object referred to by each of the elements in the collection.

 

    Iterator iter = ref.iterator();
    int cnt = 0;
    JComponent refVar;

    while(iter.hasNext()){
      refVar = (JComponent)iter.next();
      if(refVar instanceof JButton){
        refVar.setToolTipText(
                            "B"+cnt++);
      }else{

        refVar.setToolTipText(
                          "L" + cnt++);
      }//end else
    }//end while loop
    
  }//end fillIt()

Listing 4

Identifying the buttons and labels

In addition to storing a unique value in the toolTipText property
of the object referred to by each element, the code in Listing 4 also makes
it possible to distinguish between the JButton objects and the JLabel
objects.  This is accomplished by including an upper-case “B” in the
property value for each JButton, and including an upper-case “L”
in the property value for each JLabel button.

Why populate this way?

This approach to population is, admittedly, a little bit of an overkill
for illustrating what I want to illustrate in this program.  However,
I plan to use the same fillIt method in the sample program in the
next lesson, and it won’t be an overkill there.

Display the collection

The code in Listing 2 above invokes the showCollection method
to display the contents of the populated LinkedList collection. 
The showCollection method is shown in Listing 5

 

  void showCollection(Collection ref){
    Iterator iter = ref.iterator();
    while(iter.hasNext()){
      System.out.print(
             ((JComponent)iter.next()).
               getToolTipText() + " ");
    }//end while loop
    System.out.println();
  }//end showCollection

Listing 5

By now, you should have no difficulty understanding the code in Listing
5.  This code gets an iterator on the incoming reference of type Collection
The code then uses that iterator to gain access to each element in succession,
displaying the String value of the toolTipText property belonging
to a particular object during each iteration.

Downcast is required

Note that the next method of the Iterator interface returns
a reference to the next element in the collection, as type Object.

In order to invoke the getToolTipText method on the returned
reference, the reference must be downcast to type JComponent
Since both JButton and JLabel extend JComponent, and
the getToolTipText method is declared in the JComponent class,
it is not necessary to be concerned as to whether an object is type JButton
or type JLabel to display the value of the toolTipText property.
(This
is an example of polymorphic behavior based on class inheritance.)

The output for the collection

The output produced by the code in Listing 2 is shown below:

Collection contents

B0 B1 L2 B3 B4 L5

By examining the “B” and “L” characters in this output, you can identify
the JButton objects and the JLabel objects.

Copy collection elements into an array

The code in Listing 6 shows how to use the simple version of the toArray
method to create an array of type Object that contains a copy of
each element in the LinkedList collection.

 

    Object[] array = ref.toArray();

Listing 6

The toArray method

Here is some of what Sun has to say about this version of the toArray
method:

“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 this collection. … The caller is thus free to modify the
returned array.”

I will have some more to say about the safe aspects of the array
shortly.

Display the array contents

The code in Listing 7 invokes a method named showArray to cause
the current contents of the array to be displayed.

 

    System.out.println(
                 "New array contents");
    showArray(array);

Listing 7

The entire showArray method is shown in Listing 8.

 

  void showArray(Object[] array){
    for(int i = 0; i < array.length;
                                  i++){
      if(array[i] == null){
        System.out.print("null ");
      }else{
        System.out.print(
                ((JComponent)array[i]).
               getToolTipText() + " ");
      }//end else
    }//end for loop
    System.out.println();
  }//end showArray()

Listing 8

The showArray method

The behavior of the ShowArray method is straightforward. 
The method uses a for loop to access each of the elements stored
in the array in increasing index order.

A test is made to determine if the element contains a null reference. 
If so, then the word null is displayed for that element.  If
not, the getToolTipText method is used to access and display the
value of the toolTipText property for each element in the array.

The output for the array

The output produced by the code in Listing 8 is shown below:

New array contents

B0 B1 L2 B3 B4 L5

As you can see, (except for the String that identifies the type of output)
this is an exact match to the output produced when the contents of the
collection were displayed.

How “safe” is the array?

While it is “safe” to modify the contents of the array as explained
in the quotation from Sun earlier, there is still some danger here that
you need to be aware of.

Java collections do not store objects.  Rather, Java collections
store references to objects.  In Java, it is entirely possible to
have two or more references to the same object.

Array contains copies of references to objects

Each element in the array is a copy of an element in the collection.

Therefore, at this point, for each object being managed by the collection,
at least two references exist that refer to that object.  One copy
is contained in the collection.  The other copy is contained in the
collection.

If you use a reference stored in the array to modify the state of one
of those objects, that modification is made to the object that is also
referenced by an element in the collection.  This may or may not be
what you intend.  It’s not necessarily a problem as long as you understand
what is going on and be careful how you use the references stored in the
array.

Modifying the state of an object

The code shown in Listing 9 invokes the setToolTipText method
on the reference stored in the first element in the array to modify the
state of the object to which that reference refers.  Then the code
invokes the showArray method to display the contents of the array.

 

    System.out.println(
            "Modified array contents");
    ((JComponent)array[0]).
                  setToolTipText("XX");
    showArray(array);

Listing 9

The toolTipText property value for each of the objects referred
to by the remaining elements is left undisturbed.

Display array contents after object modification

The output produced by the code in Listing 9 is shown below:

Modified array contents

XX B1 L2 B3 B4 L5

As you can see, except for the first element, this is a match for the
display of the array contents before the state of the object referred by
the first element was modified.  However, the toolTipText property
for the object referred to by the first element now contains the string
“XX”, instead of the string “B0” as before.

Now, display the contents of the collection
again

The code in Listing 10 displays the state of each of the objects referred
to by the elements in the LinkedList collection.

 

    System.out.println(
                "Collection contents");
    showCollection(ref);

Listing 10

The output produced by Listing 10 is shown below:

Collection contents

XX B1 L2 B3 B4 L5

As you can see, the state of the object referred to by the reference
stored in the first element of the collection is also changed.  The
toolTipText
property for that object now contains the string “XX” instead of “B0” as
before.

The bottom line

It is safe to modify the contents of the array, even to replace the
references in the array with references to other objects.  Such a
replacement has no impact on the contents of the collection.

However, it is also possible to use the elements of the array to modify
the state of the objects referred to by the elements in the collection.

If this is what you need to do, that’s great.  However, if that
is not what you need to do, that may be a problem.  So, the bottom
line is — be careful what you do with the elements in the array.

Summary


In this lesson, I taught you how to use the simpler
version of the overloaded toArray method, declared in the Collection
interface, to copy the elements from a collection into an array of type
Object.

I also showed why you need to exercise care when
using the elements stored in the array, to avoid corrupting the state of
the objects referred to by the elements in the collection.

What’s Next?


In the next lesson, I will teach you how to use the other, more complex
version of the overloaded toArray method.

About the author

Richard Baldwin
is a college professor and private consultant whose primary focus is a
combination of Java and XML. In addition to the many platform-independent
benefits of Java applications, he believes that a combination of Java and
XML will become the primary driving force in the delivery of structured
information on the Web.

Richard has participated in numerous consulting projects involving
Java, XML, or a combination of the two.  He frequently provides onsite
Java and/or XML training at the high-tech companies located in and around
Austin, Texas.  He is the author of Baldwin’s Java Programming Tutorials,
which has gained a worldwide following among experienced and aspiring Java
programmers. He has also published articles on Java Programming in Java
Pro magazine.

Richard holds an MSEE degree from Southern Methodist University and
has many years of experience in the application of computer technology
to real-world problems.

baldwin.richard@iname.com

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories