Chapter Eight

Looping and Math Operators

by Charlie Calvert

(Download the floatops example program. Download the mathops example program. Both examples are in tar format. If you are on Windows, the WinZip utility handles the tar format.)

In this chapter you will learn how to work with while and for loops. In addition, I will show the math operators that govern basic operations such as addition, subtraction, multiplication and division. These operators work more or less exactly like the same operators that you saw in grade school math courses.

Because the material seen in this chapter is conceptually so simple, I will attempt to spice it up some by creating marginally more interesting example programs than those seen in previous chapters. In the course of creating these example programs I introduce several pieces of relatively exotic syntax. For instance, subjects that are covered in some depth in this chapter include:

As you can see, the chapter contains plenty of new material, and so it is probably worth pursuing even if you feel you already know all all about loops and how to add and multiply numbers, as no doubt, many readers already do. Other subjects that will be touched on tangentially include considerable material on using the JBuilder environment, as well as material on working with Java objects and basic Java syntax.

Enough of the introductory material. It's time now to forage ahead and see what actually lies in store for us.

Loops 

As you learned in the previous chapter, for loops and while loops are both statements. Computer programs are assembled out of statements much as houses are made out of bricks, or novels out of sentences. There are several kinds of important statements, but two of the most important of all statements are the for loop and the while loop. Not much code could be written without these essential elements.

Both for loops and while loops allow the programmer to repeat a certain block of code multiple times. In short, loops are all about repetition. 

Repetition is a bit of a dirty word for most people. We usually don't like to be involved in repetition. For instance, many repetitious jobs are considered unattractive, and everyone hated the repetition that was involved in certain kinds of school work.

It happens, however, that many creative acts are repetitious. As a tree grows, it continues to do the same thing over and over and over again, slowly adding bulk to its size. Music also involves a great deal of repetition, with certain chords patterns, or rhythmic structures being repeated numerous times. This is true even in relatively sophisticated forms of musical expression, such as jazz or a piece by J.S. Bach.

Computers allow us to take some of the strain out of repetition by automating  it. In particular, the for and while statements allow us to automate many repetitious acts.

for Loops

for loops in Java look almost exactly like for loops in C++. The syntax is the same, and their semantic significance is the same.

Consider the following simple piece of code:

  int j;
  for (int i = 0; i < 10; i++)
    j = (i * i) + 1;

This code declares two integers, one called j, the other called i. Notice that i is declared inside the for statement itself. This is perfectly legal, and is in fact considered the proper way to name the control variable in a for loop.

This loops say that it will repeat 10 times, incrementing the variable i each time the repetition occurs. Thus the variable i will start out as zero, and will be incremented ten times, until it reaches the value 9. At that point the loop will end. The code the increments the variable i looks like this: i++. I will take about the affect of the ++ unary operator later in this text.

Here is a non-compilable description of the syntax for the for loop:

 for (initialization; test; increment)
    statement

Looking back at our example, you can see that the code fragment int i = 0 is the initialization, the test or condition looks like this i < 10, and the increment look like this: i++. The increment section is poorly named, as you can either increment or decrement a variable in this part of your code. 

In the general form of the for statement shown here, you might want to call the first line the header, and the second line the body. Thus the body consists of the part called statement

In the body of the for statement you can have one or more statements which are usually set off by a set of by curly braces. You need not include the curly braces if you only include one statement in the iteration portion of the loop. 

When a for loop is executed, the initialization expression is processed first. Furthermore, it is processed only one time. The test, or condition part of the statement is then examined. If this expression evaluates to true, then execution of the for loop continues, if not the code exits the loop. At this stage, the body of the statement is executed. Whether the increment element is executed before or after the body depends a bit on the way it is written.

Here is an example of a for loop that you can try out in a JBuilder application:

  void jButton1_actionPerformed(ActionEvent e)
  {
    int j;

    for (int i = 0; i < 10; i++)
    {
      j = (i * i) + 1;
      jComboBox1.addItem(Integer.toString(j));
    }
  }

To run this code, you need to first open up JBuilder, create an application, then drop a button and a combo box on the main form. If you leave the JComboBox with its default name, then you can create an event handler for the button that looks exactly like the one shown here. As a you recall, you can create an event handler by going into design mode, selecting the JButton, turning to the Events page in the Inspector, selecting the actionperformed event, and pressing the enter key.

It happens that you can do all sorts of insane things with for loops. This license to be crazy occurs in large part because of the extreme syntactical flexibility of Java language's for loop architecture. For instance, the following two examples are perfectly legal:

for (;;)
for (int x=3, y=10; x < 100; x++, y-=3)

The first example starts an infinite loop, which you could exit by using a break or return statement:

    int x = 3;
    for (;;)
    {
      x++;
      if (x > 5)
        break;  
    }

This code is not, I'll confess, particularly sensible, but it is legal. It says, in effect, break out of this for loop only when x is larger than 5. There are simpler ways to write this code. Indeed, I very rarely find a need for such esoteric constructs. That is, however, merely a matter of personal taste, and I have met many excellent programmers who clearly luxuriate in the lush syntax made possible by the flexibility of the Java for statement. In general, I would say that this kind of flexibility is a boon to highly skilled, and very experienced programmers. For beginners, intermediate level programmers, and programmers with only modest skill sets, it is probably little more than a temptation to get into trouble.

None of this is meant to imply that the basic syntax of the for statement is complex or difficult to understand. In fact, nnce you start to understand for loops, they are really quite remarkable simple beasts. But as simple as this syntax may be, it is nonetheless one of the fundamental engines that drives much of the software in use today. for loops are used everywhere in programming in almost every language. They are one of the cornerstones on which most computer languages are built.

There will be additional examples of for loops spread throughout much of the remaining code in this chapter. Before we get to that code, however, I want to take a moment to discuss while loops.

while Loops

Like the for loop, the while loop is a fairly simple, yet nonetheless remarkably powerful, syntactical construct. The general syntax for a while loop looks like this: 

 while (expression)
   statement

Here is an example while statement that you can compile inside of JBuilder:

  void whileLoopBtn_actionPerformed(ActionEvent e)
  {
    int i = 0;

    while (i < 10)
    {
      i++;
      jComboBox1.addItem(Integer.toString(i));
    }
  }

This method begins by declaring a variable i. It then enters a while loop. The expression in the loop is evaluated. If it evaluates to true, then the body of the loop is executed. After execution, the expression is again evaluated, and the code in the body of the loop will be executed again so long as the expression yields true. If it yields false, the program breaks out of the while loop, and the body of code in the loop is skipped. Note that you must explicitly increment the variably i. If you do increment the control variable in this example, then the program will enter an infinite loop. 

NOTE: In the old days of Turbo Pascal, there was in an entry in the index for that product's documentation that read something like "infinite loop: see loop, infinite." Needless to say, if you looked up "loop, infinite," it said "see infinite loop." This is a fine example of hacker humor, and is also as good an explanation of infinite loops as one is ever likely to need. In short, the writers of the documentation had found a way to fully document a relatively complex subject without ever asking the reader to leave the index. As far as I know, this is the only example I know of where the index of a book performs the same task as the text of a book without ever needing to refer to the text of the book itself! 

Java also provides a do-while loop, which is the opposite of the while loop. It is also more or less identical to the Pascal do loop.

    do
    {
      i--;
      jComboBox1.addItem(Integer.toString(i));
    }
    while(i > 0);

The do-while statement differs from the while statement because it will be executed at least once, regardless of initial value of the variable i. In short, if you want to be sure a loop is executed at least once, use the do-while syntax, otherwise use the while syntax. 

Compulsive optimizers might like to rewrite the previous statement in this form:

    do
    {
      jComboBox1.addItem(Integer.toString(i));
    }
    while(i-- > 0);

Whether or not this code executes any more quickly than the code in the previous example I do not know. However, it is a valid alternative to the first example.

It is perhaps interesting to note that the following code does something slightly different than the code in the two previous examples:

    do
    {
      jComboBox1.addItem(Integer.toString(i));
    }
    while(--i > 0);

The code in this example will count down to one, and then break out of the loop. The code in the previous example counts down to zero before breaking out of the loop. The difference between the two examples is the use of the -- operator. In the first case, the variable is decremented after the boolean expression in the while loop is evaluated, and in the second case it is decremented before the expression is evaluated. I say all this not to drive you crazy with nit-picking details, but to begin to change the focus of the text away from looping, and onto the subject of operators and their usage in the Java language.

Listing 1: An example showing how to use most of the code discussed in the last few sections of this chapter.

 
package forloops;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Frame1 extends JFrame
{
  JPanel contentPane;
  JButton forLoopBtn = new JButton();
  JComboBox jComboBox1 = new JComboBox();
  JButton whileLoopBtn = new JButton();

  //Construct the frame
  public Frame1()
  {
    enableEvents(AWTEvent.WINDOW_EVENT_MASK);
    try
    {
      jbInit();
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
  }

  //Component initialization
  private void jbInit() throws Exception
  {
    forLoopBtn.setText("Run for loop");
    forLoopBtn.setBounds(new Rectangle(82, 141, 233, 46));
    forLoopBtn.addActionListener(new Frame1_forLoopBtn_actionAdapter(this));
    contentPane = (JPanel) this.getContentPane();
    contentPane.setLayout(null);
    this.setSize(new Dimension(400, 300));
    this.setTitle("Frame Title");
    jComboBox1.setBounds(new Rectangle(43, 36, 309, 62));
    whileLoopBtn.setText("run while loop");
    whileLoopBtn.setBounds(new Rectangle(82, 216, 233, 46));
    whileLoopBtn.addActionListener(new Frame1_whileLoopBtn_actionAdapter(this));
    contentPane.add(jComboBox1, null);
    contentPane.add(forLoopBtn, null);
    contentPane.add(whileLoopBtn, null);
  }

  //Overridden so we can exit when window is closed
  protected void processWindowEvent(WindowEvent e)
  {
    super.processWindowEvent(e);
    if (e.getID() == WindowEvent.WINDOW_CLOSING)
    {
      System.exit(0);
    }
  }

  void forLoopBtn_actionPerformed(ActionEvent e)
  {
    int j;

    for (int i = 0; i < 10; i++)
    {
      j = (i * i) + 1;
      jComboBox1.addItem(Integer.toString(j));
    }

    int x = 3;
    for (;;)
    {
      x++;
      if (x > 5)
        break;
    }
  }

  void whileLoopBtn_actionPerformed(ActionEvent e)
  {
    int i = 0;

    while (i < 10)
    {
      i++;
      jComboBox1.addItem(Integer.toString(i));
    }

    do
    {
      //i--;
      jComboBox1.addItem(Integer.toString(i));
    }
    while(i-- > 0);
  }
}

class Frame1_forLoopBtn_actionAdapter implements java.awt.event.ActionListener
{
  Frame1 adaptee;

  Frame1_forLoopBtn_actionAdapter(Frame1 adaptee)
  {
    this.adaptee = adaptee;
  }

  public void actionPerformed(ActionEvent e)
  {
    adaptee.forLoopBtn_actionPerformed(e);
  }
}

class Frame1_whileLoopBtn_actionAdapter implements java.awt.event.ActionListener
{
  Frame1 adaptee;

  Frame1_whileLoopBtn_actionAdapter(Frame1 adaptee)
  {
    this.adaptee = adaptee;
  }

  public void actionPerformed(ActionEvent e)
  {
    adaptee.whileLoopBtn_actionPerformed(e);
  }
}

Understanding Math Operators Basics

It is at last time to start exploring operators.

This section covers the basic math operators: +, -, *,% and /. These are the operators used for addition, subtraction, multiplication, getting the remainder of a division and simple division.

Name Operator Example
Addition + 1 + 1
Subtraction - 1 - 1
Multiplication * 1 * 1
Division / 1 / 1
Modulus % 1 % 1

Note that you can think of the modulus operator as the remainder operator if you so wish. It returns the remainder of the division of two numbers. For instance, 10 % 3 yields 1. But I am getting ahead of myself, as I will explain all this in detail as the rest of this chapter unfolds.

Examples of Using the JList Component

I want to give you a chance to experiment with these simple math operators. The best way to do this in a GUI program is to use a JList component. Since this is the first time we have used a JList in this text, I want to take a moment to describe how to use it.

Create a new JBuilder application, and move into design mode. Drop a JButton on your form and set its alignment to NORTH.

On the Swing page of the component palette find the JList bean and drop it down on your form. As shown in Figure 1, it should take up all the rest of the area on your form that is not already occupied by the button.

Figure 1: A button and a JList control on a form. (I used the View menu to close the Navigator and Structure panes. I did this to keep the size of the pictures you must download as small as possible.)

A JList bean has a model-view architecture, which means that one part of the component is used to handle the data and one part is used to display the data. In other words, you are really working with two different objects, one that displays data, and the other that handles the list of objects you want to display. In this case, that list of objects is just a list of strings.

As a result, you need to create the object that will handle the list of strings. I do this at the top of Frame1, where my variables that are global to the object are declared:

DefaultListModel listModel = new DefaultListModel();

Then down in the JBInit section, I set the model in the JList view:

jList2.setModel(listModel);

Alternatively, you can find the model property of the JList and set it to the DefaultListModel your created. That does the same thing as the line of code shown here.

At this stage I have two elements, the JList, which is the view, and the DefaultListModel, which is the model. Together, they make up the two halves of what people call the model view architecture for this control.

When I want to add elements to the list, I write code that looks like this:

  listModel.addElement("JBuilder");
  listModel.addElement("Delphi");

NOTE: I am oversimplifying things a bit here, just to keep the discussion moving. In particular, this architecture is sometimes called the model/view/controller (MVC) architecture. The controller part of the equation is an an object that acts as the mediator between the model and the view. That is, the controller is the object that handles the interaction between the other two objects. MVC architectures were created by Trygve Reenskaug at Xerox PARC in 1978. As such, it emerged from the same hotbed of good ideas which was eventually pillaged by Steve Jobs and Bill Gates when they created their mouse-driven, windowed environments called, respectively, the Macintosh and Windows. Much of the work at Xerox PARC was based on ideas originally developed by Doug Engelbart.

Example of Using the Math Operators

The basic math operators are simple to use. For instance, here is how to add two numbers together:

int a = 10, b = 5; c;
c = a + b;

All this is more or less completely intuitive. In this particular case, it is perhaps more interesting to see how I show that code inside of a JBuilder application. In other words, it is not difficult to understand how the + operator works, but it does take a bit of thought for newcomers to understand the code that I will write to demonstrate these simple math operators, as shown in Figure 2.

Figure 2: The output you see after selecting the Addition menu from the mathop program

To get started creating the example program shown in Figure 2 I first add a JMenuBar to the top of the main form. I then add a File menu with an exit option and an Options menu with an Addition, Multiplication, Subtraction, Division, and Remainder option, as shown in Figure 3. (If you are having trouble working with menus, go back to Chapter 06 and see the section on menus.

Figure 3: The menu from the mathops program.

Create an event to associate with the addition button, and then add code to the event handler that looks like this:

  void AdditionMenu_actionPerformed(ActionEvent e)
  {
    int a = 10, b = 5, c;

    addSpace("addition");
    listModel.addElement("c = a + b");
    c = a + b;
    listModel.addElement(c + " = " + a + " + " + b);
  }

The code appears inside a method called AddtionMenu_actionPerformed. The letters "AddtionMenu" comes from the name I gave to the menu item that contains the word Addition in its text property. The letters "actionPerformed" are assigned to this particular event, since it is the action performed when someone selects this particular menu item.

The code in the method begins by declaring three variables called a, b, c. The first two are initialized to the values 10 and 5. I then call a method that I wrote named addSpace:

  void addSpace(String opName)
  {
    listModel.addElement("-----------");
    listModel.addElement(opName);
  }

I have added this method to the program in order to provide some spacing between the elements that I print out in the listbox, as shown in Figure 2.

The addSpace method is very simple. It merely prints out a dotted line, and then whatever string you pass to the method. You will find that I call this method over and over again. If you don't like the output that this program produces, then you can change this one method, and those changes will be reflected in each part of the program that calls this method.

Let me say what I said in the last paragraph in a slightly different way, just to be sure I am communicating my point effectively. The code in this method gets called from lots of different places in this program. I could have simply hardcoded these strings into each of those locations. Instead, I opted to have them call this method. Now, if I change the way this one method works, then all the methods that call it will behave differently, in that they will print out data to the list box in a new way. If I had not done things this way, then I would have had to make changes to each method, just to change the way they wrote the separator that divided them from the previous output in the list box.

To help you understand better what I am driving at, take a look at Figure 4. It shows the output of the program after the user has chosen both the Addition and Multiplication menu items.

Figure 4: The output from the mathop program after the user has made selections from two menu items.

It may seem as though I am making a good deal of fuss about very little, but the princepal involved here is fairly important. As a programmer, one of your biggest jobs is maintaining the code you write. It needs to be tweaked, it needs to be improved, in short, it needs to be maintained. If you break your code up into logically written methods, then it will be much easier to maintain.

After calling the addSpace method, the program next displays for the user the code that is about to be executed:

    listModel.addElement("c = a + b");

The final step is to perform the actual math operation, and then to show the user the values that were actually added together and their result:

    c = a + b;
    listModel.addElement(c + " = " + a + " + " + b);

Notice the last line of code. It "strings" the variables and quoted strings together into a single string by using the + operator. The relevant code starts by listing the variable c, which is, by this time, set to 15. Then I concatenate onto that value the string " = ". Doing this yields the output "15 = ", which is indeed what gets printed in the list box. I then use the plus operator to concatenate the value of a to the string, and a simple string that looks like this: " + ". After doing this, the result printed to the screen looks like this:"15 = 10 + ". The final step is to add in the value of b, so that the string printed to the screen, looks like this: "15 = 10 + 5". You can look at Figures 3 and 4, or run the program for yourself, to confirm this value for the string.

In the previous paragraph I show two different uses for the plus operator. In one case I am using it for addition, and in another case I am using it to add strings together. You have to look at the context in which the + operator is used in order to understand whether it is meant to be an addition operator or a string concatenation operator.

The code shown here is complicated further by the fact that the raw variables a, b and c are being promoted to strings automatically by the Java compiler. This is a powerful thing for the compiler to do, but it can be confusing, since we are not doing anything to explicitly tell it to promote the value, other than using the + operator for string concatenation.

Multiplication Operators and Integers

After that rather lengthy and detailed examination of the code that shows off the addition operator, you probably are cringing a bit at the thought of seeing my explanations of the other operators. After all, if I took that long to talk about the addition operator, then at what length will I ruminate about more complicated operators such as those for division or multiplication?

Actually you need not fear. All the hard part of this section of the text is behind. Now we can look at another example, say the one for multiplication, and understand it very quickly:

  void MultiplicationMenu_actionPerformed(ActionEvent e)
  {
    int a = 10, b = 5, c;

    addSpace("multiplication");
    listModel.addElement("c = a * b");
    c = a * b;
    listModel.addElement(c + " = " + a + " * " + b);
  }

As in the previous example, the code shown here begins by declaring some variables and initializing them to simple integer values. The method then calls the addSpace method, shows the user what operation is about to take place, performs the operation, and displays the results of the operation to the user. Again, the only really tricky code here is the lengthy string concatenation that shows the values "50 = 10 * 5" to the user.

Here is the code that shows how to use the subtraction operator:

  void SubtractionMenu_actionPerformed(ActionEvent e)
  {
    int a = 10, b = 5, c;

    addSpace("subtraction");
    listModel.addElement("c = a - b");
    c = a - b;
    listModel.addElement(c + " = " + a + " - " + b);
  }

As promised, there really isn't much to say about this example. It is just like the addition sample code, only I substitute the - operator for the + operator.

Here is the code demonstrating how to divide two integer values in Java:

  void DivisionMenu_actionPerformed(ActionEvent e)
  {
    int a = 10, b = 3, c;

    addSpace("division");
    listModel.addElement("c = a / b");
    c = a / b;
    listModel.addElement(c + " = " + a + " / " + b);
  }

This code divides the number 10 by 3, which yields a result of 3. Any remainder is thrown away by the operation.

Here is the code that shows how to work with the modulus operator:

  void RemainderMenu_actionPerformed(ActionEvent e)
  {
    int a = 10, b = 3, c;

    addSpace("remainder (modulus)");
    listModel.addElement("c = a % b");
    c = a % b;
    listModel.addElement(c + " = " + a + " % " + b);
  }

The modulus operator is the opposite of the division operator: it returns the remainder of a division operation. The expression 10 / 3 yields 3, and the expression 10 % 3 yields 1, since 10 divided by 3 yields 3 with 1 left over. The expression 10 % 3 is usually pronounced 10 mod 3 or 10 modulus 3, where my preference is for the first of the two options.

At this stage you should have a fairly good grasp on the simple subject of using the basic math operators with integers. A good deal of what you saw also involved learning about working with the JList control, as well as some fairly fancy hand waving for creating and displaying strings to the user. The next section, sensibly enough, shows how to work with math operators and floating point numbers.

Math Operators and Floating Point Numbers

In this section of the chapter you will learn how to use operators with floating point numbers. To do this, I will create another example application. This application will let you work with floating point numbers, and it will allow you to learn a good deal more about the JList bean.

The basic conceit of this application, which is called floatops, is that the user can display a few rows of numbers in a JList on the left, move a certain percentage of those numbers to the JList on the right, and then perform operations on those numbers in the list on the right. For instance, he can add them all up, or multiply them together. An example of adding the numbers in the right hand list together is shown in Figure 5.

Figure 5: Adding a list of numbers.

 

I obviously could have set things up so that the user could type in the numbers that appear in the left hand list box, rather than generating them automatically. Or I could have foregone the left-hand JList altogether and had the user type things directly into the right-hand JList. Taking one of those approaches would have made the application more practical, at least from the users perspective. I didn't take that approach for two reasons:

In short, we are just having a bit of instructive fun, and are not yet to the stage where we want to struggle with the act of creating a user-friendly program that might do something useful in the real world.

Here is how we can add a series of randomly chosen floating points numbers to a JList:

  void fillListMenuItem_actionPerformed(ActionEvent e)
  {
    for (int i = 0; i < 10; i++)
    {
      Double D = new Double(Math.random() * 100.0);
      listModel.addElement(D);
    }
  }

If you come from the Delphi VCL world, as I do, this code might seem a bit peculiar at first. In particular, you might expect that it should look like this:

  void fillListMenuItem_actionPerformed(ActionEvent e)
  {
    for (int i = 0; i < 10; i++)
    {
      String S = Double.toString(Math.random() * 100.0);
      listModel.addElement(S);
    }
  }

The first example of the fillListMenuItem handler works with doubles, and the second works with strings. Both examples compile and perform as expected in Java. In the Delphi world, you tend to think of the elements in a list box as strings. But as you can see, in this case we are able to add either Doubles or Strings to the list of elements displayed in the JList.

You have to be careful here, and note that the code adds objects of type Double to the DefaultListModel, and not variables of type double. The point here is that the addElement method of the DefaultListModel object takes variables of type Object. All the Java classes descend from class Object. Furthermore, all the Java classes implement a method called toString. This means that no matter what kind of class you put in the DefaultListModel, it should, at least in theory, be able to display itself in the JList class.

By now the picture should be coming into focus. In Delphi, or indeed in most tools that developers are used to using, if you want to store elements in a JList, you can only store strings. But in Java, you can store just about any type of object in a JList, including objects of type Double. When it comes time to display each of these objects in the list, then the toString method of the Double class is called, and miraculously the value is displayed in the list box.

I like this kind of technology a lot, but it requires that developers are able to think at a fairly high level of abstraction. Objects are inherently abstract entities, and it takes awhile to get used to thinking about them in the right spirit.

Let us now revisit the code in the fillListMenuItem response method, and see how the list of doubles is made visible to the user. The code begins by creating a double with a random value between 0 and 100:

Double D = new Double(Math.random() * 100.0);

The Math.random method returns a value between 0.0 and 1.0. If you multiply the value returned by the random method by 100, then you end up with a number between 0.0 and 100.0.

Once you have a new random value to work with, you need to convert it into an object of type Double, or, perhaps more accurately, you need to wrap it up inside an object of type Double.

NOTE: As I said earlier, object oriented code is tricky to think about at times. An object of type Double is meant to fairly seamlessly wrap the type double. As a result, you should be able to think of a Double as a double, and treat it pretty much the same way in your code. C++, in fact, makes it possible for you to create a class Double such that there is almost no distinctions between a variable of type double and an object of type Double. This is in large part due to the presence in C++ of operator overloading, which is an extraordinarily powerful tool. In the right hands, operator overloading can produce miracles. Unfortunately, in the wrong hands, operator overloading creates chaos. The odds that any one programmer will make good use of operator overloading were bit low for the creators of Java, so they decided to leave operator overloading out of the language. The end result is that you have to think more consciously of the object Double as an object, and can't merely think of it as a fancy variable of type double that knows how to do all kinds of neat tricks. In particular, you have to explicitly call its toString, valueOf, toInt, toShort, and so on, methods. Explicit calls to these methods would not usually be necessary in a language that supports operator overloading.

The next part of your job is to add the random number that you created to the JList:

listModel.addElement(D);

By now, you should be able to fully appreciate the implications of being able to add objects of type double to this list rather than having to work with objects of type string. The key fact to keep in mind is that whenever there is a need to convert any object to a string, one can just call the object's toString method. According to the rules of Java, all objects must implement this method. A call to this method is exactly what the JList does internally when it needs to display an element of your list to the user, as shown in Figure 6.

Figure 6: A list of doubles displayed in a JList component. You are looking at a list of strings, but internally, the JList is really maintaining a list of Doubles.

When looking at Figure 6, you can see that it performs the operation of printing random numbers in the JList ten times. We have seen in some detail how each individual instance of this operation occurs. Here is the code that makes it repeat ten times:

for (int i = 0; i < 10; i++)

As you know, this type of code is called a for loop. It allows you to execute a particular block of code x number of times.

In particular, the code shown here sets the variable i to 0, and then increments it 10 times. Each time it increments the variable, the code inside the body of the for loop gets called. Here is the whole loop to study once again:

    for (int i = 0; i < 10; i++)
    {
      String S = Double.toString(Math.random() * 100.0);
      listModel.addElement(S);
    }

The two lines of code inside the block statement that follows the first line of code gets called ten times, one for each count of the variable i between and including the value 0, and up to but excluding the value 10. 

Moving an Item from One JList to Another

As you recall, this example program works with two JLists. The list on the left presents the user with a randomly selected group of numbers. By clicking on any one of these numbers the user can move that number from the left hand list to the right hand list. Once it is in the right hand list, the user can perform operations on the numbers, such as addition, or multiplication.

Here is code that will allow you to move one of the items on the left hand JList over to the JList on the right.

  /** Get the selected item and move it from the list on the left to
      the list on the right, deleting it from the list on the left. */
  void jList1_mouseClicked(MouseEvent e)
  {
    // JList.getSelectedIndex gets the currently selected item in the list.
    // listModel.get retrieves the currently selected object in the list.
    // We know the object is actually a Double, so we can typecast it.
    Double D = (Double)listModel.get(jList1.getSelectedIndex());
    listModel.remove(jList1.getSelectedIndex());
    mathList.addElement(D);
  }

NOTE: I don't talk much about commenting your code, and in fact I am often remiss in my practice of this most valuable of the coder's arts. In this one case, at least, I provide an example of this virtuous practice.

This method will be called when the user clicks on a particular number in the left hand list box. The goal is to delete that number from the JList on the left, and move it to the JList on the right. The first step in this process is to find the number the user selected:

Double D = (Double)listModel.get(jList1.getSelectedIndex());

A call to jList1.getSelectedIndex will retrieve the index of the item that the user has selected from the left-hand list. The first element in the list is item 0, the second item 1, and so on. If the user has selected the third item in the list, then getSelectedIndex will return the integer value 2.

A call to listModel.get(2) would retrieve the third item in the DefaultListModel object referenced by the identifier listModel. A DefaultListModel works with items of type Object. Object is the root object from which all Java objects descend. So in this case, I must typecast the value returned by a call to the get method. In particular the value is typecast as a Double, which is in fact that type of object we have stored in this list. (Forgive me if I am using a bit of repetition to drive home points that I feel deserve special emphasis.)

The end result of all these peregrinations is a return of the value the user selected with the mouse. The next step is to remove it from the current list, and add it to the list on the right:

    listModel.remove(jList1.getSelectedIndex());
    mathList.addElement(D);

The first line of code here calls the remove method of the DefaultListModel object. As you can see, I pass in the index of the item I want to remove. I get the index by called jList1.getSelectedIndex. If I had desired to do so, I could have saved the value from my previous call to this method rather than calling it twice. Optimizations of that type are something I would explore if I found the application was performing poorly, and I thought minor changes to the code would rectify the problem. In this case I felt that the program was performing fine, and I felt that a change of this type to the code was very unlikely to significantly alter its performance. In short, I was being lazy.

Once I had deleted the item from the list on the left, I added it to the list on the right by calling the addElement method of the DefaultListModel object. At that stage, I was done with this rather simple operation.

Adding Up a List of Numbers

It is now time to see how to add up or multiply all the numbers in the list on the right. The mechanisms for doing each of these procedures are nearly identical. In particular, both operations involve iterating over all the items in the second list box, then either adding or multiplying the list of items together.

Because the two operations are so nearly identical, I have decided to throw in some variety by presenting two different ways to iterate over the items in the second JList. In the first technique, the one I use when adding the numbers, I show a standard way to iterate over items in a list. In the second example, the one involving multiplication, I show a special kind of iterator that is specific to Java.

Here is code for iterating through all the numbers in the JList on the right and displaying the result:

  void addMenuItem_actionPerformed(ActionEvent e)
  {
    double total = 0;
    Double num;

    int Count = mathList.getSize();

    for (int i = 0; i < Count; i++)
    {
      num = (Double)mathList.get(i);
      total = total + num.doubleValue();
    }
    mathList.addElement("-----------");
    mathList.addElement(Double.toString(total));
  }

The code begins by calling the getSize method of the DefaulListModel object to get the number of objects in the list. I then perform a for loop to iterate over each item in the list. The for statement shown here executes Count number of times, with the variable i incrementing from 0 to Count-1 during the life of the for loop.

I call the get method of the DefaultListModel to retrieve the first element in the list. I then add that number to a variable called total that was initially set to zero. If the first item in the list was 1.72, then after the first iteration of the for loop, the value of total gets set to 1.72. Suppose the second time through the loop the value of the double retrieved from the list happened to be 48.28. If that were the case, then after the second time through the loop, total would be equal to 50.0. The process would be repeated each time the loop executed until the program ran out of numbers to add together.

Once the program was out of number to add, it would insert a line of hyphens in the list box, and then print out an answer by calling the Double.toString method on the current value of the total variable. (Remember that you can call the toString method of the Double object without creating an instance of it because toString is declared as a static method.)

You might suppose that by this time I have completely forgotten the main topic of this chapter, which is operators. Fortunately, that matter has not entirely slipped my mind, though we certainly have drifted far from the topic at times! At any rate, the main reason you are looking at this code is simply to see that the plus operator works exactly the same way with floating point numbers as it does with integers. 

Multiplying a list of Numbers Together

This code will multiply all the numbers in the second list box together, rather than adding them together:

  void multiplyMenuItem_actionPerformed(ActionEvent e)
  {
    double total = 1;
    Double num;

    Enumeration mathEnum = mathList.elements();

    while (mathEnum.hasMoreElements())
    {
      num = (Double)mathEnum.nextElement();
      total = total * num.doubleValue();
    }

    mathList.addElement("-----------");
    mathList.addElement(Double.toString(total));
  }
}

This code is very like the code used to add numbers. The main difference, besides the usage of the multiplication operator instead of the addition operator, is the use of an Enumeration.

It happens that the DefaultListModel object is really just a fairly thin wrapper around another important Java object called a Vector. In fact, as you have been learning how to use the DefaultListModel, you have really been learning the basic principles that underlie the Java Vector class.

A vector, as you know doubt know, is just a list, or an array, of items. In our case, we have been working with a vector of Objects, and in particular, a vector of Double objects. In the addition example, we saw how to iterate over the members of that vector, by retrieving each of the Double objects in our list one at a time. 

It turns out that the Vector object, and hence the DefaultListModel, has a special means for allowing you to iterate over its members. The code for performing that operation looks like this:

    Enumeration mathEnum = mathList.elements();

    while (mathEnum.hasMoreElements())
    {
      mathEnum.nextElement();
      ....
    }

The first line show here calls the elements method of the Vector or DefaultListModel class in order to retrieve an object called an Enumeration. To use the Enemuration object, you must be sure that you first import the java.util.* classes at the top of your java file:

package floatops;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;

The Enumeation object has two methods, one called hasMoreElements and the other called nextElement. By using these two methods you can iterate over all the elements in a Vector.

In particular, you write code that says that you should keep calling the nextElement method to retrieve the next element from the list so long as the hasMoreElements method returns true. Remember that a while loop lets you perform a particular operation over and over again, so long as a particular expression evaluates to true.

I won't spend any more time discussing the rest of the code for the multiplication method, since it is so nearly identical to the code for the addition method. If necessary, spend some time studying it until it begins to make sense to you.

I will leave examples of working with the /, - and % operators in a context similar to the ones shown here as an exercise for the reader. 

Floating Point Operations and Accuracy

It is probably worth emphasizing that floating point addition, subtraction, multiplication and division on computers is not a precise science. If assign a variable of type float to the value .05 and then add it to itself three times, the result is not necessarily going to be .15. In fact, it is highly unlikely that you will get precisely that number. Instead, you will probably return a value that is close to that value, but not exactly right on the money.

Consider the following code:

    double a = 0.05;
    double b = 0;
    for (x = 0; x < 5; x++)
    {
      b = b + a;
      jComboBox1.addItem(Double.toString(b));
    }

On my computer, it produces these results:

0.05
0.1
0.1500000000000002
0.2
0.25

That's not a problem with Java, that's just the way it goes when you use floating point types on a computer. As a result, you should convert your dollar values to pennies, and use integer values, or a specially prepared set of tools, if you want to use a computer to track money.

Review of Promoting and Converting Types

We are nearly a the end of this long chapter, but before closing I'm going to review some material covered in the previous chapters. As you recall, math operators, as a rule, preserve the type that you are using. If you use integers in your code, you will get an integer as a result:

  int b, c;   // declare integers
  int  a = b + c;     // result will be an integer

Conversely, if you declared all your variables as a double, then you would get a double as a result.

if you use both a double and an int in an expression, then the result of a basic math operation will be a double.

  int a;
  double b; 

  double c = a + b;

If you tried to do things the other way around, you would get an error:

  int a;
  double b;

  int c = a + b;

In particular, the code shown in the last example would give you a loss of precession error. You can force the compiler to cooperate by using a typecast:

  int a;
  double b;

  int c = (int)(a + b);

What we are really doing here is telling the compiler to ignore the rule and believe that we know what we are doing. This is not a figure of speech, it is literally what we are saying to the compiler. The code says: "I know you would normally complain about this kind of error, but I know what I'm doing, trust me!"

To sum up: If you want to assign a smaller type to a larger type, you must use a typecast. If you use two different types in an expression, the result will be at least as large as the larger of the two types.

If you add two bytes, two shorts or some combination of bytes and shorts together the result will be promoted to an int. This is because the compilers we are working with use 32 bit math. There are 32 bits in an int, and hence the int is the native type for the compiler. As a result, the compiler can work more efficiently with an int than with a short. Therefore they promote the result of adding two bytes together to an int. If you want to see this topic discussed in more depth, turn back to Chapter Six.

Increment, Decrement and Assignment Operators.

The increment and decrement operators look like this: ++, --. Typically you use them with a variable, as in these examples: i++ or i--. 



In previous examples shown in this chapter I have demonstrated how to use the increment and decrement operators. In particular, in the example for using the do-while loop, I showed the difference between pre-decrement and post-decrement operators. As you recall, those examples looked like this:

    do
    {
      jComboBox1.addItem(Integer.toString(i));
    }
    while(i-- > 0);

    do
    {
      jComboBox1.addItem(Integer.toString(i));
    }
    while(--i > 0);

In the first example shown here you see the post-decrement operator in the expression that controls the do-while loop. A post-decrement operator will cause the variable i to be decremented by one after it is compared to the constant 0. The pre-decrement operator does the opposite, that is it compares the values after i is decremented. 

Another type of operator is the assignment operator, which looks like this: =. We have seen many examples of suing the assignment operator throughout this text. It's use is entirely intuitive, and needs no commentary.

Consider this code, which you say earlier in this chapter:

    double a = 0.05;
    double b = 0;
    for (x = 0; x < 5; x++)
    {
      b = b + a;
      jComboBox1.addItem(Double.toString(b));
    }

Without chaning its meaning, it can be altered to look like this:

    double a = 0.05;
    double b = 0;
    for (int x = 0; x < 5; x++)
    {
      b += a;
      jComboBox1.addItem(Double.toString(b));
    }

This code uses the standard assignment operator in the first few statements, but in the midst of the for loop it is uses the += operator. The += operator is just a shorthand way of b = b + a. In other words, there is no significant difference between writing b = b + a and writing b += a. Other operators of this type include *=, /=, %=, and -=.

There is no particular reason, other than peer pressure, to use either the a = a + 1 or the a += 1 syntax. It all amounts to the same thing, and you can use the style of coding that best suits your tastes. 

These kinds of shorthand assignment operators are inherited directly from  the C/C++ language. Once upon a time, compiler writers found it simpler to optimize code written in the second style, but those days are long gone. Code of either type now executes exactly the same. Given those circumstances, I personally choose to avoid the shorthand notation, since it can be a bit confusing. Ultimately, however, both syntaxes are correct.

Summary

Quite a bit of material was covered in this chapter. In particular, you saw how to work with for statements, while statements, and do-while statements. The text then explored the subject of basic math operators as they behave when working with both floating point numbers and integers.

You saw how to work with pre and post increment and decrement operators, which allow you to write code that looks like this: i++; --j; In these examples, the first is the post-increment operator and the second is the pre-decrement operator. I also briefly discussed the assignment operators.

Another major topic covered in this chapter was the JList object, and its companion, the DefaultListModel. Both of these objects proved more formidable topics of discussion than either looping or math operators. In particular, I had to delve into a broad overview of the model-view architecture before I could find a way to explain how this tool works.