9. Arrays and nested loops
Suppose we want to make an applet that displays lotto numbers. As you saw in chapter 8, you can make such numbers by using the method random from the Math class. Drawing a lotto number (1 through 42) could be done like this:
int number = (int)(42 * Math.random()) + 1;
If we draw six of these numbers and display them, our program seems OK, but there is a problem: the program could draw the same number several times. How to prevent this?

In order to check whether or not a number has been drawn before, we must have some way to store the numbers. A convenient way to do that is by using numbered variables.

Simple numbered variables could look like this:
number0 = (int)(42 * Math.random()) + 1;
number1 = (int)(42 * Math.random()) + 1;
number2 = (int)(42 * Math.random()) + 1;
number3 = (int)(42 * Math.random()) + 1;
number4 = (int)(42 * Math.random()) + 1;
number5 = (int)(42 * Math.random()) + 1;
But we still have to use the names of all six variables. There is a much better way to use numbered variables, which is called an array. Arrays differ from the variables we used above, in that the numbers are put in square brackets, like this:
number[0] = (int)(42 * Math.random()) + 1;
number[1] = (int)(42 * Math.random()) + 1;
number[2] = (int)(42 * Math.random()) + 1;
number[3] = (int)(42 * Math.random()) + 1;
number[4] = (int)(42 * Math.random()) + 1;
number[5] = (int)(42 * Math.random()) + 1;

"No big deal", you might think. But the strength of this concept is made clear when we replace the number in brackets (the so-called index) by a variable. 

Look how easy it is to fill the six variables with random numbers (1-42) in the following way:

for (int i=0; i<6; i++)
        number[i] = (int)(42 * Math.random()) + 1;
It will be clear that the advantage of using an array will even be greater if we use an array of hundreds (if not thousands) of such numbered variables. Another use of an array could be to contain the number of days of each month, for instance in the following way:
month[1] = 31; // January
month[2] = 28; // February
month[3] = 31; // March, etc.
If you want to use an array of variables, you'll have to declare them (just like any other variable). This can be done in two steps, like this:
int month[ ];
month = new int [12];
The first line is called the declaration of the array, the second is called the initialization. The first line is sometimes written like this:
int [ ] month;
You can combine the two lines in this way:
int month[ ] = new int [12];
Or you could, of course, write it like this:
int [ ] month = new int [12];

You can even declare, initialize and fill an array with values at the same time in the following way:

int month[ ] = {31,28,31,30,31,30,31,31,30,31,30,31};
If you want to declare six lotto numbers, it could be done like this:
int lotto[ ] = new int [6];
And filling the array could be done in this way:
for (int i=0; i<6; i++)
        lotto[i] = (int)(42 * Math.random()) + 1;
But still, this doesn't exclude the possibility of drawing the same number twice. A good way to avoid doubles is by comparing any number with all the numbers that were made earlier. This could be done as shown in the program below:
// Six lotto numbers (1-42) are drawn.
import java.applet.*;
import java.awt.*;
public class LottoNumbers extends Applet {
Button button = new Button("clcik");
String text = "Click for a new set of lotto-numbers";

public void init () {
        add(button);
}

public void paint (Graphics g) {
        g.drawString (text, 30, 120);
}

public boolean action (Event e, Object o) {
if (e.target==button) {
        int lotto[ ] = new int [6];
        boolean drawn;
        for (int i=0; i<6; i++) {
                do {
                        drawn = false;
                        lotto[i] = (int)(42*Math.random())+ 1;
                        for (int j=0; j<i; j++)
                                if (lotto[i] == lotto[j])
                                        drawn = true;
                } while (drawn);
        }
        text = "";
        for (int i=0; i<6; i++)
                text += lotto[i] + "   ";
        repaint();
        return true;
}
return false;
}
}
        

As you can see, this program makes a loop (with control-variable j) within the loop with control-variable i. The situation where one loop finds itself within another loop, is called nested loops.

In the loop with control variable j, the program checks whether the newly generated number has been drawn before. For that we use the boolean drawn. We keep generating new numbers until a number is generated that was not drawn before. This is done in the following way:

do {
        drawn = false;
        lotto[i] = (int)(42*Math.random())+ 1;
        for (int j=0; j<i; j++)
                if (lotto[i] == lotto[j])
                        drawn = true;
} while (drawn);

Simple sorting
Lotto numbers are usually represented from small to large. Therefore, it would be better if we sort the numbers generated by our program.

There is a very simple way to sort numbers (called the Bubble Sort). It works like this: compare each number (except the last) to the one that follows it. If they are in the wrong order (large-small), then exchange them and make a note that the numbers were 'unsorted'. We keep doing this until during a complete round no numbers have been exchanged. The sorting process itself looks like this:

boolean unsorted;
do {
        unsorted = false;
        for (int i=0; i<5; i++)
                if (lotto[i] > lotto[i+1]) {
                        int temp = lotto[i];   // In these three lines
                        lotto[i] = lotto[i+1];  // lotto[i] and lotto[i+1]
                        lotto[i+1] = temp;    // are exchanged
                        unsorted = true;
                }
} while (unsorted);


A simulation of this process can be seen in the following applet:

       

Finally, here is the complete Lotto applet:

         

Arrays can be made of almost any kind of objects, such as booleans, floats, strings, buttons and textfields. When objects are involved that have to be initialized separately, not only the array has to be initialized, but also each object separately. 

How that is done in practice, can be seen in the following program:
// An array of 10 buttons
import java.applet.*;
import java.awt.*;
public class TenButtons extends Applet {
String text = "Click any of the buttons ..";
Button buttons[ ] = new Button [10];
public void init () {
        for (int i=0; i<10; i++) {
                buttons [ i ] = new Button ("" + i );
                add (buttons [ i ]);
        } 
}
public void paint (Graphics g) {
        g.drawString (text, 30, 120);
}
public boolean action (Event e, Object o) {
        for (int i=0; i<10; i++) {
                if (e.target == buttons [ i ] )  {
                        text = "You clicked button " + i;
                        repaint();
                        return true;
                }
        }
        return false;
}
}
A working specimen of this applet can be seen down here:

           

Another example of an array of objects is an array of strings. You could, for instance,  make an array of strings with the days of the week in the following way:

String days [ ] = {"Monday", "Tuesday", "Wednesday", "Thursday",
"Friday", "Saturday", "Sunday"};
And if you want to display a list of the days of the week, you could write the following two lines in the paint method of an applet:
for (int i=0; i<7; i++)
        g.drawString (days[i], 20, 20 + i * 30);
The resulting applet can be seen here:

           

Exercise 9.1
Rewrite exercise 8.1 in such a way that the proverbs are stored in an array of strings. You must also use the switch-case construction which was discussed in chapter 8.

Exercise 9.2
Make an applet in which you can type a number (1 through 12). After clicking a button, the applet will display the name of the corresponding month. The program must report if no month is associated with the number typed.

Exercise 9.3
Make an applet in which a chessboard is drawn (8x8 squares, alternately white and black) with the help of two nested loops. You can fill a rectangle with colour by using the method fillRect, which works exactly like drawRect. Don't forget to set a colour with setColor(), a method that we discussed in chapter 4.

To chapter 10

Main Menu Java Tutorial

To home page

(C) 2003, Thomas Luif, Amsterdam