Figure 9-1: Which way to go?
Chapter 9
Forks in the Road
In This Chapter
Writing statements that choose between alternatives
Putting statements inside one another
Writing several kinds of decision-making statements
Here’s an excerpt from Beginning Programming with Java For Dummies, 3rd Edition, Chapter 2:
If you’re trying to store words or sentences (not just single letters), then you need to use something called a String.*
The excerpt illustrates two important points: First, you may have to use something called a String. Second, your choice of action can depend on something’s being true or false.
If it’s true that you’re trying to store words or sentences,
you need to use something called a String.
This chapter deals with decision-making, which plays a fundamental role in the creation of instructions. With the material in this chapter, you expand your programming power by leaps and bounds.
Decisions, Decisions!
Picture yourself walking along a quiet country road. You’re enjoying a pleasant summer day. It’s not too hot, and a gentle breeze from the north makes you feel fresh and alert. You’re holding a copy of this book, opened to Chapter 9. You read the paragraph about storing words or sentences, and then you look up.
* This excerpt is reprinted with permission from John Wiley & Sons, Inc. If you can’t find a copy of Beginning Programming with Java For Dummies, 3rd Edition in your local bookstore, visit http://www.wiley.com
.
You see a fork in the road. You see two signs — one pointing to the right; the other pointing to the left. One sign reads, “Storing words or sentences? True.” The other sign reads, “Storing words or sentences? False.” You evaluate the words-or-sentences situation and march on, veering right or left depending on your software situation. A diagram of this story is shown in Figure 9-1.
Figure 9-1: Which way to go?
Life is filled with forks in the road. Take an ordinary set of directions for heating up a frozen snack:
Microwave cooking directions:
Place on microwave-safe plate.
Microwave on high for 2 minutes.
Turn product.
Microwave on high for 2 more minutes.
Conventional oven directions:
Preheat oven to 350 degrees.
Place product on baking sheet.
Bake for 25 minutes.
Again, you choose between alternatives. If you use a microwave oven, do this. Otherwise, do that.
In fact, it’s hard to imagine useful instructions that don’t involve choices. If you’re a homeowner with two dependents earning more than $30,000 per year, check here. If you don’t remember how to use curly braces in Java programs, see Chapter 4. Did the user correctly type his password? If yes, then let the user log in; if no, then kick the bum out. If you think the market will go up, then buy stocks; otherwise, buy bonds. And if you buy stocks, which should you buy? And when should you sell?
Making Decisions (Java if Statements)
When you work with computer programs, you make one decision after another. Almost every programming language has a way of branching in one of two directions. In Java (and in many other languages), the branching feature is called an if statement. Check out Listing 9-1 to see an if
statement.
Listing 9-1: An if Statement
if (randomNumber > 5) {
System.out.println(“Yes. Isn’t it obvious?”);
} else {
System.out.println(“No, and don’t ask again.”);
}
To see a complete program containing the code from Listing 9-1, skip to Listing 9-2 (or, if you prefer, walk, jump, or run to Listing 9-2).
The if
statement in Listing 9-1 represents a branch, a decision, two alternative courses of action. In plain English, this statement has the following meaning:
If the
randomNumber variable’s value is greater than 5,
display
“Yes. Isn’t it obvious?” on the screen.
Otherwise,
display
“No, and don’t ask again.” on the screen.
Pictorially, you get the fork shown in Figure 9-2.
Looking carefully at if statements
An if
statement can take the following form:
if (
Condition
) {
SomeStatements
} else {
OtherStatements
}
Figure 9-2: A random number decides your fate.
To get a real-life if
statement, substitute meaningful text for the three placeholders Condition
, SomeStatements
, and OtherStatements
. Here’s how I make the substitutions in Listing 9-1:
I substitute
randomNumber > 5
for Condition
.
I substitute
System.out.println(“Yes. Isn’t it obvious?”);
for SomeStatements
.
I substitute
System.out.println(“No, and don’t ask again.”);
for OtherStatements
.
The substitutions are illustrated in Figure 9-3.
Sometimes I need alternate names for parts of an if
statement. I call them the if clause and the else clause.
if (
Condition
) {
if clause
} else {
else clause
}
Figure 9-3: An if statement and its format.
An if
statement is an example of a compound statement — a statement that includes other statements within it. The if
statement in Listing 9-1 includes two println
calls, and these calls to println
are statements.
Notice how I use parentheses and semicolons in the if
statement of Listing 9-1. In particular, notice the following:
The condition must be in parentheses.
Statements inside the
if
clause end with semicolons. So do statements inside the else
clause.
There’s no semicolon immediately after the condition.
There’s no semicolon immediately after the word
else
.
As a beginning programmer, you may think these rules are arbitrary. But they’re not. These rules belong to a very carefully crafted grammar. They’re like the grammar rules for English sentences, but they’re even more logical! (Sorry, Kelly.)
Table 9-1 shows you the kinds of things that can go wrong when you break the if
statement’s punctuation rules. The table’s last two items are the most notorious. In these two situations, the compiler doesn’t catch the error. This lulls you into a false sense of security. The trouble is, when you run the program, the code’s behavior isn’t what you expect it to be.
As you compose your code, it helps to think of an if
statement as one indivisible unit. Instead of typing the whole first line (condition and all), try typing the if
statement’s skeletal outline.
if ()
{
//To do: Fill in the condition.
//To do: Fill in SomeStatements.
} else {
//To do: Fill in OtherStatements.
}
With the entire outline in place, you can start working on the items on your to-do list. When you apply this kind of thinking to a compound statement, it’s harder to make a mistake.
A complete program
Listing 9-2 contains a complete program with a simple if
statement. The listing’s code behaves like an electronic oracle. Ask the program a yes or no question, and the program answers you back. Of course, the answer to your question is randomly generated. But who cares? It’s fun to ask anyway.
Listing 9-2: I Know Everything
import java.util.Scanner;
import java.util.Random;
class AnswerYesOrNo {
public static void main(String args[]) {
Scanner myScanner = new Scanner(System.in);
Random myRandom = new Random();
int randomNumber;
System.out.print(“Type your question, my child: “);
myScanner.nextLine();
randomNumber = myRandom.nextInt(10) + 1;
if (randomNumber > 5) {
System.out.println(“Yes. Isn’t it obvious?”);
} else {
System.out.println(“No, and don’t ask again.”);
}
}
}
Figure 9-4 shows several runs of the program in Listing 9-2. The program’s action has four parts:
Figure 9-4: The all-knowing Java program in action.
1. Prompt the user.
Call System.out.print
, telling the user to type a question.
2. Get the user’s question from the keyboard.
In Figure 9-4, I run the AnswerYesOrNo
program four times, and I type a different question each time. Meanwhile, back in Listing 9-2, the statement
myScanner.nextLine();
swallows up my question and does absolutely nothing with it. This is an anomaly, but you’re smart, so you can handle it.
Normally, when a program gets input from the keyboard, the program does something with the input. For example, the program can assign the input to a variable:
amount = myScanner.nextDouble();
Alternatively, the program can display the input on the screen:
System.out.println(myScanner.nextLine());
But the code in Listing 9-2 is different. When this AnswerYesOrNo
program runs, the user has to type something. (The call to getLine
waits for the user to type some stuff and then press Enter.) But the AnswerYesOrNo
program has no need to store the input for further analysis. (The computer does what I do when my wife asks me if I plan to clean up after myself. I ignore the question and make up an arbitrary answer.) So the program doesn’t do anything with the user’s input. The call to myScanner.nextLine
just sits there in a statement of its own, doing nothing, behaving like a big black hole. It’s unusual for a program to do this, but an electronic oracle is an unusual thing. It calls for some slightly unusual code.
3. Get a random number — any int
value from 1 to 10.
Okay, wise guys. You’ve just trashed the user’s input. How will you answer yes or no to the user’s question?
No problem! None at all! You’ll display an answer randomly. The user won’t know the difference. (Hah, hah!) You can do this as long as you can generate random numbers. The numbers from 1 to 10 will do just fine.
In Listing 9-2, the stuff about Random
and myRandom
looks very much like the familiar Scanner
code. From a beginning programmer’s point of view, Random
and Scanner
work almost the same way. Of course, there’s an important difference. A call to the Random
class’s nextInt(10)
method doesn’t fetch anything from the keyboard. Instead, this nextInt(10)
method gets a number out of the blue.
The name Random
is defined in the Java API. The call to myRandom.nextInt(10)
in Listing 9-2 gets a number from 0 to 9. Then my code adds 1 (making a number from 1 to 10) and assigns that number to the variable randomNumber
. When that’s done, you’re ready to answer the user’s question.
In Java’s API, the word
Random
is the name of a Java class, and nextInt
is the name of a Java method. For more information on the relationship between classes and methods, see Chapters 17, 18, and 19.
4. Answer yes or no.
Calling myRandom.nextInt(10)
is like spinning a wheel on a TV game show. The wheel has slots numbered 1 to 10. The if
statement in Listing 9-2 turns your number into a yes or no alternative. If you roll a number that’s greater than 5, the program answers yes. Otherwise (if you roll a number that’s less than or equal to 5), the program answers no.
You can trust me on this one. I’ve made lots of important decisions based on my AnswerYesOrNo
program.
Indenting if statements in your code
Notice how, in Listing 9-2, the println
calls inside the if
statement are indented. Strictly speaking, you don’t have to indent the statements that are inside an if
statement. For all the compiler cares, you can write your whole program on a single line or place all your statements in an artful, misshapen zigzag. The problem is, if you don’t indent your statements in some logical fashion, then neither you nor anyone else can make sense of your code. In Listing 9-2, the indenting of the println
calls helps your eye (and brain) see quickly that these statements are subordinate to the overall if
/else
flow.
In a small program, unindented or poorly indented code is barely tolerable. But in a complicated program, indentation that doesn’t follow a neat, logical pattern is a big, ugly nightmare.
Variations on the Theme
I don’t like to skin cats. But I’ve heard that, if I ever need to skin one, I have a choice of several techniques. I’ll keep that in mind the next time my cat Histamine mistakes the carpet for a litter box.*
*Rick Ross, who read about skinning cats in one of my other books, sent me this information via e-mail: “. . . on page 10 you refer to ‘skinning the cat’ and go on to discuss litter boxes and whatnot. Please note that the phrase ‘more than one way to skin a cat’ refers to the difficulty in removing the inedible skin from catfish, and that there is more than one way to do same. These range from nailing the critter’s tail to a board and taking a pair of pliers to peel it down, to letting the furry kind of cat have the darn thing and just not worrying about it. I grew up on The River (the big one running north/south down the US that begins with ‘M’ and has so many repeated letters), so it’s integral to our experience there. A common misconception (if inhumane and revolting). Just thought you’d want to know.”
Anyway, whether you’re skinning catfish, skinning kitties, or writing computer programs, the same principle holds true. You always have alternatives. Listing 9-2 shows you one way to write an if
statement. The rest of this chapter (and all of Chapter 10) show you some other ways to create if
statements.
. . . Or else what?
You can create an if
statement without an else
clause. For example, imagine a web page on which one in ten randomly chosen visitors receives a special offer. To keep visitors guessing, I call the Random
class’s nextInt
method, and make the offer to anyone whose number is lucky 7.
If
myRandom.nextInt(10) + 1
generates the number 7, display a special offer message.
If
myRandom.nextInt(10) + 1
generates any number other than 7, do nothing. Don’t display a special offer message and don’t display a discouraging, “Sorry, no offer for you,” message.
The code to implement such a strategy is shown in Listing 9-3. A few runs of the code are shown in Figure 9-5.
Listing 9-3: Aren’t You Lucky?
import java.util.Random;
class SpecialOffer {
public static void main(String args[]) {
Random myRandom = new Random();
int randomNumber = myRandom.nextInt(10) + 1;
if (randomNumber == 7) {
System.out.println(“An offer just for you!”);
}
System.out.println(randomNumber);
}
}
Figure 9-5: Three runs of the code in Listing 9-3.
The if
statement in Listing 9-3 has no else
clause. This if
statement has the following form:
if (
Condition
) {
SomeStatements
}
When randomNumber
is 7, the computer displays An offer just for you!
When randomNumber
isn’t 7, the computer doesn’t display An offer just for you!
The action is illustrated in Figure 9-6.
Figure 9-6: If you have nothing good to say, then don’t say anything.
In Listing 9-3, I took the liberty of adding an extra println
. This println
(at the end of the main
method) displays the random number generated by my call to nextInt
. On a webpage with special offers, you probably wouldn’t see the randomly generated number, but I can’t test my SpecialOffer
code without knowing what numbers the code generates.
Anyway, notice that the value of randomNumber
is displayed in every run. The println
for randomNumber
isn’t inside the if
statement. (This println
comes after the if
statement.) So the computer always executes this println
. Whether randomNumber == 7
is true or false, the computer takes the appropriate if
action, and then marches on to execute System.out.println(randomNumber)
.
Packing more stuff into an if statement
Here’s an interesting situation: You have two baseball teams — the Hankees and the Socks. You want to display the teams’ scores on two separate lines, with the winner’s score coming first. (On the computer screen, the winner’s score is displayed above the loser’s score. In case of a tie, you display the two identical scores, one above the other.) Listing 9-4 has the code.
Listing 9-4: May the Best Team Be Displayed First
import java.util.Scanner;
import static java.lang.System.in;
import static java.lang.System.out;
class TwoTeams {
public static void main(String args[]) {
Scanner myScanner = new Scanner(
in
);
int hankees, socks;
out.print(“Hankees and Socks scores? “);
hankees = myScanner.nextInt();
socks = myScanner.nextInt();
out.println();
if (hankees > socks) {
out.print(“Hankees: “);
out.println(hankees);
out.print(“Socks: “);
out.println(socks);
} else {
out.print(“Socks: “);
out.println(socks);
out.print(“Hankees: “);
out.println(hankees);
}
}
}
Figure 9-7 has a few runs of the code. (To show a few runs in one figure, I copied the results from Eclipse’s Console view to Windows Notepad.)
With curly braces, a bunch of print
and println
calls are tucked away safely inside the if
clause. Another group of print
and println
calls are squished inside the else
clause. This creates the forking situation shown in Figure 9-8.
Figure 9-7: See? The code in Listing 9-4 really works!
Figure 9-8: Cheer for your favorite team.
Some handy import declarations
When I wrote this section’s example, I was tired of writing the word System
. After all, Listing 9-4 has ten System.out.print
lines. By this point in the book, shouldn’t my computer remember what out.print
means?
Of course, computers don’t work that way. If you want a computer to “know” what out.print
means, you have to code that knowledge somewhere inside the Java compiler.
Fortunately for me, the ability to abbreviate things like System.out.print
is available from Java 5.0 onward. (An older Java compiler just chokes on the code in Listing 9-4.) This ability to abbreviate things is called static import. It’s illustrated in the second and third lines of Listing 9-4.
Whenever I start a program with the line
import static java.lang.System.out;
I can replace System.out
with plain out
in the remainder of the program. The same holds true of System.in
. With an import declaration near the top of Listing 9-4, I can replace new Scanner(System.in)
with the simpler new Scanner(in)
.
You may be wondering what all the fuss is about. If I can abbreviate java.util.Scanner
by writing Scanner
, what’s so special about abbreviating System.out
? And why do I have to write out.print
? Can I trim System.out.print
down to the single word print
? Look again at the first few lines of Listing 9-4. When do I need the word static
? And what’s the difference between java.util
and java.lang
?
I’m sorry. My response to these questions won’t thrill you. The fact is, I can’t explain away any of these issues until Chapter 18. Before I can explain static import declarations, I need to introduce some ideas. I need to describe classes, packages, and static members.
So until you reach Chapter 18, please bear with me. Just paste three import declarations to the top of your Java programs and trust that everything will work well.