Chapter 15

The Old Runaround

IN THIS CHAPTER

check Creating repetitive actions

check Improving your nesting techniques

check Insisting on a valid response from the user

check Looping through enumerated values

Iremember it distinctly — the sense of dread I would feel on the way to Aunt Edna’s house. She was a kind old woman, and her intentions were good. But visits to her house were always agonizing.

First, we’d sit in the living room and talk about other relatives. That was okay, as long as I understood what people were talking about. Sometimes, the gossip would be about adult topics, and I’d become bored.

After all the family chatter, my father would help Aunt Edna with her bills. That was fun to watch because Aunt Edna had a genetically inherited family ailment: Like me and many of my ancestors, Aunt Edna couldn’t keep track of paperwork to save her life. It was as if the paper had allergens that made Aunt Edna’s skin crawl. After ten minutes of useful bill paying, my father would find a mistake, an improper tally, or something else in the ledger that needed attention. He’d ask Aunt Edna about it, and she’d shrug her shoulders. He’d become agitated trying to track down the problem, while Aunt Edna rolled her eyes and smiled with ignorant satisfaction. It was great entertainment.

Then, when the bill paying was done, we’d sit down to eat dinner. That’s when I would remember why I dreaded these visits. Dinner was unbearable. Aunt Edna believed in Fletcherism — a health movement whose followers chewed each mouthful of food 100 times. The more devoted followers used a chart, with a different number for the mastication of each kind of food. The minimal number of chews for any food was 32 — one chomp for each tooth in your mouth. People who did this said they were “Fletcherizing.”

Mom and Dad thought the whole Fletcher business was silly, but they respected Aunt Edna and felt that people her age should be humored, not defied. As for me, I thought I’d explode from the monotony. Each meal lasted forever. Each mouthful was an ordeal. I can still remember my mantra — the words I’d say to myself without meaning to do so:

I’ve chewed 0 times so far.
Have I chewed 100 times yet? If not, then
Chew!
Add 1 to the number of times that I’ve chewed.
Go back to "Have I chewed" to find out if I’m done yet.

Repeating Statements a Certain Number of Times ( Java for Statements)

Life is filled with examples of counting loops. And computer programming mirrors life ( … or is it the other way around?). When you tell a computer what to do, you’re often telling the computer to print three lines, process ten accounts, dial a million phone numbers, or whatever. Because counting loops are common in programming, the people who create programming languages have developed statements just for loops of this kind. In Java, the statement that repeats something a certain number of times is called a for statement. An example of a for statement is in Listing 15-1.

LISTING 15-1 Horace Fletcher’s Revenge

import static java.lang.System.out;

class AuntEdnaSettlesForTen {

public static void main(String args[]) {

for (int count = 0; count < 10; count++) {
out.print("I’ve chewed ");
out.print(count);
out.println(" time(s).");
}

out.println("10 times! Hooray!");
out.println("I can swallow!");
}
}

Figure 15-1 shows you what you get when you run the program in Listing 15-1:

  • The for statement in Listing 15-1 starts by setting the count variable equal to 0.
  • Then the for statement tests to make sure that count is less than 10 (which it certainly is).
  • Then the for statement dives ahead and executes the printing statements between the curly braces. At this early stage of the game, the computer prints I’ve chewed 0 time(s).
  • Then the for statement executes count++ — that last thing inside the for statement’s parentheses. This last action adds 1 to the value of count.
image

FIGURE 15-1: Chewing ten times.

This ends the first iteration of the for statement in Listing 15-1. Of course, this loop has more to it than just one iteration:

  • With count now equal to 1, the for statement checks again to make sure that count is less than 10. (Yes, 1 is smaller than 10.)
  • Because the test turns out okay, the for statement marches back into the curly-braced statements and prints I’ve chewed 1 time(s) on the screen.
  • Then the for statement executes that last count++ inside its parentheses. The statement adds 1 to the value of count, increasing the value of count to 2.

And so on. This whole thing keeps repeating over and over again until, after ten iterations, the value of count finally reaches 10. When this happens, the check for count being less than 10 fails, and the loop’s execution ends. The computer jumps to whatever statement comes immediately after the for statement. In Listing 15-1, the computer prints 10 times! Hooray! I can swallow! The whole process is illustrated in Figure 15-2.

image

FIGURE 15-2: The action of the for loop in Listing 15-1.

The anatomy of a for statement

A typical for statement looks like this:

for (Initialization; Condition; Update) {
Statements
}

After the word for, you put three things in parentheses: an initialization, a condition, and an update.

Each of the three items in parentheses plays its own, distinct role:

  • Initialization: The initialization is executed once, when the run of your program first reaches the for statement.
  • Condition: The condition is tested several times (at the start of each iteration).
  • Update: The update is also evaluated several times (at the end of each iteration).

If it helps, think of the loop as though its text is shifted all around:

//This is NOT real code
int count = 0
for count < 0 {
out.print("I’ve chewed ");
out.print(count);
out.println(" time(s).");
count++;
}

You can’t write a real for statement this way. (The compiler would throw code like this right into the garbage can.) Even so, this is the order in which the parts of the for statement are executed.

warning The first line of a for statement (the word for followed by stuff in parentheses) isn’t a complete statement. So you almost never put a semicolon after the stuff in parentheses. If you make a mistake and type a semicolon, like this:

// DON’T DO THIS:
for (int count = 0; count < 10; count++) ; {

you usually put the computer into a do-nothing loop. The computer counts to itself from 0 to 9. After counting, the computer executes whatever statements come immediately after the open curly brace. (The loop ends at the semicolon, so the statements after the open curly brace aren’t inside the loop.)

Initializing a for loop

Look at the first line of the for loop in Listing 15-1 and notice the declaration int count = 0. That’s something new. When you create a for loop, you can declare a variable (like count) as part of the loop initialization.

If you declare a variable in the initialization of a for loop, you can’t use that variable outside the loop. For example, in Listing 15-1, try putting out.println(count) after the end of the loop:

//This code does not compile.
for (int count = 0; count < 10; count++) {
out.print("I’ve chewed ");
out.print(count);
out.println(" time(s).");
}

out.print(count); //The count variable doesn’t exist here.

With this extra reference to the count variable, the compiler gives you an error message. You can see the message in Figure 15-3. If you’re not experienced with for statements, the message may surprise you — “Whadaya mean ‘count cannot be resolved to a variable’? There’s a count variable declaration just four lines above that statement.” Ah, yes. But the count variable is declared in the for loop’s initialization. Outside the for loop, that count variable doesn’t exist.

image

FIGURE 15-3: What count variable? I don’t see a count variable.

To use a variable outside of a for statement, you have to declare that variable outside the for statement. You can even do this with the for statement’s counting variable. Listing 15-2 has an example.

LISTING 15-2 Using a Variable Declared Outside of a for Loop

import static java.lang.System.out;

class AuntEdnaDoesItAgain {

public static void main(String args[]) {
int count;

for (count = 0; count < 10; count++) {
out.print("I’ve chewed ");
out.print(count);
out.println(" time(s).");
}

out.print(count);
out.println(" times! Hooray!");
out.println("I can swallow!");
}
}

A run of the code in Listing 15-2 looks exactly like the run for Listing 15-1. The run is pictured in Figure 15-1. Unlike its predecessor, Listing 15-2 enjoys the luxury of using the count variable to display the number 10. It can do this because in Listing 15-2, the count variable belongs to the entire main method and not to the for loop alone.

Notice the words for (count = 0 in Listing 15-2. Because count is declared before the for statement, you don’t declare count again in the for statement’s initialization. I tried declaring count twice, as in the following code:

//This does NOT work:
int count;

for (int count = 0; count < 10; count++) {
… etc.

And Eclipse told me to clean up my act:

Duplicate local variable count ^

Using Nested for Loops

Because you’re reading Beginning Programming with Java For Dummies, 5th Edition, I assume that you manage a big hotel. Chapter 16 tells you everything you need to know about hotel management. But before you begin reading that chapter, you can get a little preview in this section.

I happen to know that your hotel has 9 floors, and that each floor of your hotel has 20 rooms. On this sunny afternoon, someone hands you a flash drive containing a file full of numbers. You copy this hotelData file to your hard drive and then display the file in Eclipse’s editor. You see the stuff shown in Figure 15-4.

image

FIGURE 15-4: A file containing hotel occupancy data.

This file gives the number of guests in each room. For example, at the start of the file, you see 2 1 2. This means that, on the first floor, Room 1 has 2 guests, Room 2 has 1 guest, and Room 3 has 2 guests. After reading 20 of these numbers, you see 0 2 2. So, on the second floor, Room 1 has 0 guests, Room 2 has 2 guests, and Room 3 has 2 guests. The story continues until the last number in the file. According to that number, Room 20 on the ninth floor has 4 guests.

You’d like a more orderly display of these numbers — a display of the kind in Figure 15-5. So you whip out your keyboard to write a quick Java program.

image

FIGURE 15-5: A readable display of the data in Figure 15-4.

As in some other examples, you decide which statements go where by asking yourself how many times each statement should be executed. For starters, the display in Figure 15-5 has 9 lines, and each line has 20 numbers:

for (each of 9 floors)
for (each of 20 rooms on a floor)
get a number from the file and display the number on the screen.

So your program has a for loop within a for loop — a pair of nested for loops.

Next, you notice how each line begins in Figure 15-5. Each line contains the word Floor, followed by the floor number. Because this Floor display occurs only 9 times in Figure 15-5, the statements to print this display belong in the for-each-of-9-floors loop (and not in the for-each-of-20-rooms loop). The statements should be before the for-each-of-20-rooms loop because this Floor display comes once before each line’s 20-number display:

for (each of 9 floors)
display "Floor" and the floor number,
for (each of 20 rooms on a floor)
get a number from the file and display the number on the screen.

You’re almost ready to write the code. But there’s one detail that’s easy to forget. (Well, it’s a detail that I always forget.) After displaying 20 numbers, the program advances to a new line. This new-line action happens only 9 times during the run of the program, and it always happens after the program displays 20 numbers:

for (each of 9 floors)
display "Floor" and the floor number,
for (each of 20 rooms on a floor)
get a number from the file and display the number on the screen,
Go to the next line.

That does it. That’s all you need. The code to create the display of Figure 15-5 is in Listing 15-3.

LISTING 15-3 Hey! Is This a For-by-For?

import java.util.Scanner;
import java.io.File;
import java.io.FileNotFoundException;
import static java.lang.System.out;

class DisplayHotelData {

public static void main(String args[]) throws FileNotFoundException {

Scanner diskScanner = new Scanner(new File("hotelData"));

for (int floor = 1; floor <= 9; floor++) {
out.print("Floor ");
out.print(floor);
out.print(": ");

for (int roomNum = 1; roomNum <= 20; roomNum++) {
out.print(diskScanner.nextInt());
out.print(’ ’);
}

out.println();
}

diskScanner.close();
}
}

The code in Listing 15-3 has the variable floor going from 1 to 9 and has the variable roomNum going from 1 to 20. Because the roomNum loop is inside the floor loop, the writing of 20 numbers happens 9 times. That’s good. It’s exactly what I want.

tryitout When it comes to writing code with loops, there’s no such thing as having too much practice. Try these problems. Work slowly and don’t get discouraged. Remember that solutions are available at www.allmycode.com/BeginProg.

NARCISSIST’S CODE

Write a program that reads the user’s name and a number (howMany) from the keyboard. The program uses a for loop to display the user’s name howMany times on the screen.

BRITISH POUNDS TO US DOLLARS

In April 2017, one British pound is worth 1.25 US dollars. Write a program to create a simple currency conversion table. In your program, use a for loop to display the following table:

Pounds Dollars
1 1.25
2 2.5
3 3.75
4 5.0
5 6.25
6 7.5
7 8.75
8 10.0
9 11.25

MYSTERY CODE

This experiment comes in two parts:

  • Without running the following code, try to predict what the code’s output will be:

    for (int row = 0; row < 5; row++) {
    for (int column = 0; column < 5; column++) {
    System.out.print("*");
    }
    System.out.println();
    }

    After making your prediction, run the code to find out whether your prediction is correct.

  • The code in this bullet is a slight variation on the code in the previous bullet. First, try to predict what the code will output. Then run the code to find out whether your prediction is correct:

    for (int row = 0; row < 5; row++) {
    for (int column = 0; column <= row; column++) {
    System.out.print("*");
    }
    System.out.println();
    }

DRAW A PATTERN

This experiment comes in four parts:

  • Write a program that reads a number from the keyboard. The program uses a for loop to display that number of dashes.

    For example, if the user types the number 5, the program displays

    -----

  • Modify the program that you wrote in the previous bullet. The modified program uses two for loops to display two lines of characters. The second line is one character shorter than the first line. For example, if the user types the number 7, the program displays

    -------
    ------

  • Modify the program that you wrote in the previous bullet. The modified program uses nested for loops to display several lines of characters, each shorter than the line that comes before it. For example, if the user types the number 5, the program displays

    -----
    ----
    ---
    --
    -

    Hint: The code in this program is much like one of the earlier “Mystery code” snippets.

  • For an extra challenge, modify the code you wrote in the previous bullet so that it displays a slash (/) at the end of each line. For example, if the user types the number 5, the program displays

    ----/
    ---/
    --/
    -/
    /

TIMES TABLE

This experiment comes in four parts:

  • Write a program that reads a number from the keyboard. The program uses a for loop to display all numbers up to and including that number. For example, if the user types 9, the program displays

    1 2 3 4 5 6 7 8 9

    tip To put space between the numbers, refer to the “Escapism” sidebar in Chapter 12.

  • Write a program that reads a number from the keyboard. The program uses a for loop to display two times 1, two times 2, and so on up to and including two times the user’s number. For example, if the user types 9, the program displays

    2 4 6 8 10 12 14 16 18

  • Write a program that uses nested for loops to display a multiplication table.

    1 2 3 4 5 6 7 8 9
    2 4 6 8 10 12 14 16 18
    3 6 9 12 15 18 21 24 27
    4 8 12 16 20 24 28 32 36
    5 10 15 20 25 30 35 40 45
    6 12 18 24 30 36 42 48 54
    7 14 21 28 35 42 49 56 63
    8 16 24 32 40 48 56 64 72
    9 18 27 36 45 54 63 72 81

  • For an extra challenge, add a header row and header column to your multiplication table. The resulting display looks like this:

    1 2 3 4 5 6 7 8 9
    ---------------------------------------------------------
    1 |1 2 3 4 5 6 7 8 9
    2 |2 4 6 8 10 12 14 16 18
    3 |3 6 9 12 15 18 21 24 27
    4 |4 8 12 16 20 24 28 32 36
    5 |5 10 15 20 25 30 35 40 45
    6 |6 12 18 24 30 36 42 48 54
    7 |7 14 21 28 35 42 49 56 63
    8 |8 16 24 32 40 48 56 64 72
    9 |9 18 27 36 45 54 63 72 81

Repeating Until You Get What You Need (Java do Statements)

I introduce Java’s while loop in Chapter 12. When you create a while loop, you write the loop’s condition first. After the condition, you write the code that gets repeatedly executed.

while (Condition) {
Code that gets repeatedly executed
}

This way of writing a while statement is no accident. The look of the statement emphasizes an important point — that the computer always checks the condition before executing any of the repeated code.

If the loop’s condition is never true, the stuff inside the loop is never executed — not even once. In fact, you can easily cook up a while loop whose statements are never executed (although I can’t think of a reason why you would ever want to do it):

//This code doesn’t print anything:
int twoPlusTwo = 2 + 2;
while (twoPlusTwo == 5) {
System.out.println("Are you kidding?");
System.out.println("2+2 doesn’t equal 5.");
System.out.print ("Everyone knows that");
System.out.println(" 2+2 equals 3.");
}

In spite of this silly twoPlusTwo example, the while statement turns out to be the most useful of Java’s looping constructs. In particular, the while loop is good for situations in which you must look before you leap. For example: “While money is in my account, write a mortgage check every month.” When you first encounter this statement, if your account has a zero balance, you don’t want to write a mortgage check — not even one check.

But at times (not many), you want to leap before you look. In a situation when you’re asking the user for a response, maybe the user’s response makes sense, but maybe it doesn’t. Maybe the user’s finger slipped, or perhaps the user didn’t understand the question. In many situations, it’s important to correctly interpret the user’s response. If the user’s response doesn’t make sense, you must ask again.

Getting a trustworthy response

Consider a program that deletes a file. Before deleting the file, the program asks for confirmation from the user. If the user types Y, delete; if the user types N, don’t delete. Of course, deleting a file is serious stuff. Mistaking a bad keystroke for a “yes” answer can delete the company’s records. (And mistaking a bad keystroke for a “no” answer can preserve the company’s incriminating evidence.) If there’s any doubt about the user’s response, the program should ask the user to respond again.

Pause a moment to think about the flow of actions — what should and shouldn’t happen when the computer executes the loop. A loop of this kind doesn’t need to check anything before getting the user’s first response. Indeed, before the user gives the first response, the loop has nothing to check. The loop shouldn’t start with “as long as the user’s response is invalid, get another response from the user.” Instead, the loop should just leap ahead, get a response from the user, and then check the response to see whether it made sense. The code to do all of this is in Listing 15-4.

LISTING 15-4 Repeat Before You Delete

/*
* DISCLAIMER: Neither the author nor John Wiley & Sons,
* Inc., nor anyone else even remotely connected with the
* creation of this book, assumes any responsibility
* for any damage of any kind due to the use of this code,
* or the use of any work derived from this code,
* including any work created partially or in full by
* the reader.
*
* Sign here:_______________________________
*/

import java.io.File;
import java.util.Scanner;

class IHopeYouKnowWhatYoureDoing {

public static void main(String args[]) {

Scanner keyboard = new Scanner(System.in);
char reply;

do {

System.out.print("Reply with Y or N…");
System.out.print(" Delete the importantData file? ");
reply = keyboard.findWithinHorizon(".", 0).charAt(0);

} while (reply != ’Y’ && reply != ’N’);

if (reply == ’Y’) {
new File("importantData.txt").delete();
System.out.println("Deleted!");
} else {
System.out.println("No harm in asking!");
}

keyboard.close();
}
}

Deleting a file

A run of the Listing 15-4 program is shown in Figure 15-6. Before deleting a file, the program asks the user whether it’s okay to do the deletion. If the user gives one of the two expected answers (Y or N), the program proceeds according to the user’s wishes. But if the user enters any other letter (or any digit, punctuation symbol, or whatever), the program asks the user for another response.

image

FIGURE 15-6: No! Don’t do it!

In Figure 15-6, the user hems and haws for a while, first with the letter U, and then with the digit 8, and then with lowercase letters. Finally, the user enters Y, and the program deletes the importantData.txt file. If you compare the files on your hard drive (before and after the run of the program), you’ll see that the program trashes the file named importantData.txt.

If you use Eclipse, here’s how you can tell that a file is being deleted:

  1. Create a Java project containing the code in Listing 15-4.

    If you followed the steps in Chapter 2 for importing this book’s examples, you can skip this create-a-project step and use the existing 15-04 project.

  2. In the Package Explorer, select the project.

    remember Don’t select any of the project’s subfolders. (For example, don’t select the project’s src folder.) Instead, select the project’s root. For more info about a project’s root, see Chapter 13.

  3. In Eclipse’s main menu, choose File ⇒ New ⇒ File.

    Eclipse’s New File dialog box appears.

    tip In the New File dialog box, make sure that the name of your project’s root folder is in the box’s Enter or Select the Parent Folder field. For example, if you followed the steps in Chapter 2 for importing this book’s examples, make sure that 15-04 (and no other text) appears in the Enter or Select the Parent Folder field.

  4. In the dialog box’s File Name field, type the name of your new file.

    Type importantData.txt.

  5. Click Finish.
  6. Observe that the file’s name appears in Eclipse’s Package Explorer.

    The name is in the 15-04 project’s root directory. You put it in the root directory because, in Listing 15-4, the name importantData.txt (with no slashes or backslashes) refers only to a name in the project’s root directory. The program’s run has no effect on any files outside of the root directory, even if any of those files has the name importantData.txt.

    crossreference To find out how to refer to files outside of the project’s root directory, refer to Chapter 13.

    For this experiment, you don’t have to add any text to the file. The file exists only to be deleted.

  7. Run the program.

    When the program runs, type Y to delete the importantData.txt file.

    After running the program, you want to check to make sure that the program deleted the importantData.txt file.

  8. In the Package Explorer, select the project’s root (again, for good measure).
  9. On Eclipse’s main menu, choose File ⇒ Refresh.

    Eclipse takes another look at the project directory and lists the directory’s files in the Package Explorer’s tree. Assuming that the program did its job correctly, the file named importandData.txt no longer appears in the tree.

In Listing 15-4, the statement

new File("importantData.txt").delete();

is tricky. At first glance, you seem to be creating a new file, only to delete that file in the same line of code! But in reality, the words new File create only a representation of a file inside your program. To be more precise, the words new File create, inside your program, a representation of a disk file that may or may not already exist on your computer’s hard drive. Here’s what the new File statement really means:

"Let new File("importantData.txt") refer to a file named importantData.txt. If such a file exists, then delete it."

Yes, the devil is in the details. But smiles are in the subtleties and nobility is in the nuance.

Using Java’s do statement

To write the program in Listing 15-4, you need a loop — a loop that repeatedly asks the user whether the importantData.txt file should be deleted. (The action of the loop in Listing 15-4 is illustrated in Figure 15-7.) The loop continues to ask until the user gives a meaningful response. The loop tests its condition at the end of each iteration, after each of the user’s responses.

image

FIGURE 15-7: Here we go loop, do loop.

That’s why the program in Listing 15-4 has a do loop (also known as a do … while loop). With a do loop, the program jumps right in, executes some statements, and then checks a condition. If the condition is true, the program goes back to the top of the loop for another go-around. If the condition is false, the computer leaves the loop (and jumps to whatever code comes immediately after the loop).

A closer look at the do statement

The format of a do loop is

do {
Statements
} while (Condition)

Writing the Condition at the end of the loop reminds me that the computer executes the Statements inside the loop first. After the computer executes the Statements, the computer goes on to check the Condition. If the Condition is true, the computer goes back for another iteration of the Statements.

With a do loop, the computer always executes the statements inside the loop at least once:

//This code prints something:
int twoPlusTwo = 2 + 2;
do {
System.out.println("Are you kidding?");
System.out.println("2+2 doesn’t equal 5.");
System.out.print ("Everyone knows that");
System.out.println(" 2+2 equals 3.");
} while (twoPlusTwo == 5);

This code displays Are you kidding? 2+2 doesn’t equal 5 … and so on and then tests the condition twoPlusTwo == 5. Because twoPlusTwo == 5 is false, the computer doesn’t go back for another iteration. Instead, the computer jumps to whatever code comes immediately after the loop.

tryitout Get some practice using Java’s do statement.

DO I HEAR AN ECHO?

In a do statement, repeatedly read numbers from the keyboard. Display each number back to the user on the screen. After displaying a number, ask whether the user wants to continue entering numbers. When the user replies with the letter n, stop.

Here’s a sample run of the program:

Enter a number: 5
5
Continue? (y/n) y

Enter a number: 81
81
Continue? (y/n) y

Enter a number: 29
29
Continue? (y/n) n

Done!

TALLY HO!

In a do statement, repeatedly read int values from the keyboard and keep track of the running total. The user says, “I want to stop entering values” by typing one final int value — the value 0. At that point, the program displays the total of all values that the user entered.

Repeating with Predetermined Values (Java’s Enhanced for Statement)

Most people say that they “never win anything.” Other people win raffles, drawings, and contests, but they don’t win things. Well, I have news for these people: Other people don’t win things, either. Nobody wins things. That’s how the laws of probability work. Your chance of winning one of the popular U.S. lottery jackpots is roughly 1 in 135 million. If you sell your quarter-million-dollar house and use all the money to buy lottery tickets, your chance of winning is still only 1 in 540. If you play every day of the month (selling a house each day), your chance of winning the jackpot is still less than 1 in 15.

Of course, nothing in the previous paragraph applies to me. I don’t buy lottery tickets, but I often win things. My winning streak started a few years ago. I won some expensive Java software at the end of an online seminar. Later that month, I won a microchip-enabled pinky ring (a memento from a 1998 Java conference). The following year, I won a wireless PDA. Just last week, I won a fancy business-class printer.

I never spend money to enter any contests. All these winnings are freebies. When the national computer science educators’ conference met in Reno, Nevada, my colleagues convinced me to try the slot machines. I lost $23, and then I won back $18. At that point, I stopped playing. I wanted to quit while I was only $5 behind.

That’s why my writing a Java program about slot machines is such a strange occurrence. A typical slot machine has three reels, with each reel having about 20 symbols. But to illustrate this section’s ideas, I don’t need 20 symbols. Instead, I use 4 symbols — a cherry, a lemon, a kumquat, and a rutabaga.

Creating an enhanced for loop

When you play my simplified slot machine, you can spin any one of over 60 combinations — cherry+cherry+kumquat, rutabaga+rutabaga+rutabaga, or whatever. This chapter’s goal is to list all possible combinations. But first, I show you another kind of loop. Listing 15-5 defines an enum type for a slot machine’s symbols and displays a list of the symbols. (For an introduction to enum types, see Chapter 10.)

LISTING 15-5 Slot Machine Symbols

import static java.lang.System.out;

class ListSymbols {

enum Symbol {
cherry, lemon, kumquat, rutabaga
}

public static void main(String args[]) {
for (Symbol leftReel : Symbol.values()) {
out.println(leftReel);
}
}
}

Listing 15-5 uses Java’s enhanced for loop. The word enhanced means “enhanced compared with the loops in earlier versions of Java.” The enhanced for loop was introduced in Java version 5.0. If you run Java version 1.4.2 (or something like that), you can’t use an enhanced for loop.

Here’s the format of the enhanced for loop:

for (TypeName variableName : RangeOfValues) {
Statements
}

Here’s how the loop in Listing 15-5 follows the format:

  • In Listing 15-5, the word Symbol is the name of a type.

    The int type describes values like –1, 0, 1, and 2. The boolean type describes the values true and false. And (because of the code in Listing 15-5) the Symbol type describes the values cherry, lemon, kumquat, and rutabaga. For more information on enum types like Symbol, see Chapter 10.

  • In Listing 15-5, the word leftReel is the name of a variable.

    The loop in Listing 15-1 defines count to be an int variable. Similarly, the loop in Listing 15-5 defines leftReel to be a Symbol variable. So, in theory, the variable leftReel can take on any of the four Symbol values.

    By the way, I call this variable leftReel because the code lists all symbols that can appear on the leftmost of the slot machine’s three reels. Because all three of the slot machine’s reels have the same symbols, I may also have named this variable middleReel or rightReel. But on second thought, I’ll save the names middleReel and rightReel for a later example.

  • In Listing 15-5, the expression Symbol.values() stands for the four values in Listing 15-5.

    To quote myself from the previous bullet, “in theory, the variable leftReel can take on any of the four Symbol values.” Well, the RangeOfValues part of the for statement turns theory into practice. This third item inside the parentheses says, “Have as many loop iterations as there are Symbol values, and have the leftReel variable take on a different Symbol value during each of the loop’s iterations.”

    So the loop in Listing 15-5 undergoes four iterations: an iteration in which leftReel has value cherry, another iteration in which leftReel has value lemon, a third iteration in which leftReel has value kumquat, and a fourth iteration in which leftReel has value rutabaga. During each iteration, the program prints the leftReel variable’s value. The result is in Figure 15-8.

image

FIGURE 15-8: The output of the code in Listing 15-5.

In general, a someEnumTypeName.values() expression stands for the set of values that a particular enum type’s variable can have. For example, back in Listing 10-7 in Chapter 10, you can use the expression WhoWins.values() to refer to the home, visitor, and neither values.

tip The difference between a type’s name (like Symbol) and the type’s values (as in Symbol.values()) is really subtle. Fortunately, you don’t have to worry about the difference. As a beginning programmer, you can just use the .values() suffix in an enhanced loop’s RangeOfValues part.

Nesting the enhanced for loops

Listing 15-5 solves a simple problem in an elegant way. After reading about Listing 15-5, you may ask about more complicated problems: “Can I list all possible 3-reel combinations of the slot machine’s four symbols?” Yes, you can. Listing 15-6 shows you how to do it.

LISTING 15-6 Listing the Combinations

import static java.lang.System.out;

class ListCombinations {

enum Symbol {
cherry, lemon, kumquat, rutabaga
}

public static void main(String args[]) {

for (Symbol leftReel : Symbol.values()) {
for (Symbol middleReel : Symbol.values()) {
for (Symbol rightReel : Symbol.values()) {
out.print(leftReel);
out.print(" ");
out.print(middleReel);
out.print(" ");
out.println(rightReel);
}
}
}
}
}

When you run the program in Listing 15-6, you get 64 lines of output. Some of those lines (from the middle of a run) are shown in Figure 15-9.

image

FIGURE 15-9: Some lines of output from the code in Listing 15-6.

Like the code in Listing 15-3, the program in Listing 15-6 contains a loop within a loop. In fact, Listing 15-6 has a loop within a loop within a loop. Here’s the strategy in Listing 15-6:

for (each of the 4 symbols that can appear on the left reel),
for (each of the 4 symbols that can appear on the middle reel),
for (each of the 4 symbols that can appear on the right reel),
display the three reels’ symbols.

You start the outer loop with the cherry symbol. Then you march on to the middle loop and begin that loop with the cherry symbol. Then you proceed to the inner loop and pick the cherry (pun intended). At last, with each loop tuned to the cherry setting, you display the cherry cherry cherry combination. (See Figure 15-10.)

image

FIGURE 15-10: Entering loops for the first time in the program of Listing 15-6.

After displaying cherry cherry cherry, you continue with other values of the innermost loop. That is, you change the right reel’s value from cherry to lemon. (See Figure 15-11.) Now the three reels’ values are cherry cherry lemon, so you display these values on the screen.

image

FIGURE 15-11: Changing from cherry to lemon in the innermost loop.

After exhausting the four values of the innermost (right reel) loop, you jump out of that innermost loop. But the jump puts you back to the top of the middle loop, where you change the value of middleReel from cherry to lemon. Now the values of leftReel and middleReel are cherry and lemon, respectively. (See Figure 15-12.)

image

FIGURE 15-12: Changing from cherry to lemon in the middle loop.

Having changed to lemon on the middle loop, you go barreling again into the innermost loop. As if you’d never seen this inner loop, you set the loop’s variable to cherry. (See Figure 15-13.)

image

FIGURE 15-13: Restarting the inner loop.

After displaying the tasty cherry lemon cherry combination, you start changing the values of the innermost loop. (See Figure 15-14.)

image

FIGURE 15-14: Traveling a second time through the innermost loop.

The loop keeps going until it displays all 64 combinations. Whew!

tryitout To finish off this chapter, you write code for the paper-scissors-stone game.

ENUMERATE THE POSSIBILITIES

Create an enum type containing the three values in the paper-scissors-stone game. Write a program that uses an enhanced for loop to display the three values.

SHOW YOUR HANDS

Use nested enhanced for statements to show all the possibilities when two players compete against one another in the paper-scissors-stone game. The output of your program will look something like this:

paper paper
paper scissors
paper stone
scissors paper
… and so on

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.217.254.118