Chapter 10

Which Way Did He Go?

IN THIS CHAPTER

check Untangling complicated conditions

check Writing cool conditional code

check Intertwining your if statements

It’s tax time again. At the moment, I’m working on Form 12432-89B. Here’s what it says:

If you’re married with fewer than three children, and your income is higher than the EIQ (Estimated Income Quota), or if you’re single and living in a non-residential area (as defined by Section 10, Part iii of the Uniform Zoning Act), and you’re either self-employed as an LLC (Limited Liability Company) or you qualify for veterans’ benefits, then skip Steps 3 and 4 or 4, 5, and 6, depending on your answers to Questions 2a and 3d.

No wonder I have no time to write! I’m too busy interpreting these tax forms.

Anyway, this chapter deals with the potential complexity of if statements. This chapter has nothing as complex as Form 12432-89B, but if you ever encounter something that complicated, you’ll be ready for it.

Forming Bigger and Better Conditions

In Listing 9-2 (refer to Chapter 9), the code chooses a course of action based on one call to the Random class’s nextInt method. That’s fine for the electronic oracle program described in Chapter 9, but what if you’re rolling a pair of dice? In backgammon and other dice games, rolling 3 and 5 isn’t the same as rolling 4 and 4, even though the total for both rolls is 8. The next move varies, depending on whether you roll doubles. To get the computer to roll two dice, you execute myRandom.nextInt(6) + 1 two times. Then you combine the two rolls into a larger, more complicated if statement.

To simulate a backgammon game (and many other, more practical situations) you need to combine conditions:

If die1 + die2 equals 8 and die1 equals die2, …

You need things like and and or — things that can wire conditions together. Java has operators to represent these concepts, which are described in Table 10-1 and illustrated in Figure 10-1.

TABLE 10-1 Logical Operators

Operator Symbol

Meaning

Example

Illustration

&&

and

4 < age && age < 8

Figure 10-1(a)

||

or

age < 4 || 8 < age

Figure 10-1(b)

!

not

!eachKidGetsTen

Figure 10-1(c)

image

FIGURE 10-1: When you satisfy a condition, you’re happy.

Combined conditions, like the ones in Table 10-1, can be mighty confusing. That’s why I tread carefully when I use such things. Here’s a short explanation of each example in the table:

  • 4 < age && age < 8

    The value of the age variable is greater than 4 and is less than 8. The numbers 5, 6, 7, 8, 9 … are all greater than 4. But among these numbers, only 5, 6, and 7 are less than 8. So only the numbers 5, 6, and 7 satisfy this combined condition.

  • age < 4 || 8 < age

    The value of the age variable is less than 4 or is greater than 8. To create the or condition, you use two pipe symbols. On many U.S. English keyboards, you can find the pipe symbol immediately above the Enter key (the same key as the backslash, but shifted).

    In this combined condition, the value of the age variable is either less than 4 or greater than 8. For example, if a number is less than 4, the number satisfies the condition. Numbers like 1, 2, and 3 are all less than 4, so these numbers satisfy the combined condition.

    Also, if a number is greater than 8, the number satisfies the combined condition. Numbers like 9, 10, and 11 are all greater than 8, so these numbers satisfy the condition.

  • !eachKidGetsTen

    If I weren’t experienced with computer programming languages, I’d be confused by the exclamation point. I’d think that !eachKidGetsTen means, “Yes, each kid does get ten.” But that’s not what this expression means. This expression says, “The variable eachKidGetsTen does not have the value true.” In Java and other programming languages, an exclamation point stands for negative, for no way, for not.

    Listing 8-4 (refer to Chapter 8) has a boolean variable named eachKidGetsTen. A boolean variable’s value is either true or false. Because ! means not, the expressions eachKidGetsTen and !eachKidGetsTen have opposite values. So when eachKidGetsTen is true, !eachKidGetsTen is false (and vice versa).

tip Java’s || operator is inclusive. This means that you get true whenever the thing on the left side is true, the thing on the right side is true, or both things are true. For example, the condition 2 < 10 || 20 < 30 is true.

warning In Java, you can’t combine comparisons the way you do in ordinary English. In English, you may say, “We’ll have between three and ten people at the dinner table.” But in Java, you get an error message if you write 3 <= people <= 10. To do this comparison, you need something like 3 <= people && people <= 10.

Combining conditions: An example

Here’s a handy example of the use of logical operators. A movie theater posts its prices for admission:

  • Regular price: $9.25
  • Kids under 12: $5.25
  • Seniors (65 and older): $5.25

Because the kids’ and seniors’ prices are the same, you can combine these prices into one category. (That’s not always the best programming strategy, but do it anyway for this example.) To find a particular moviegoer’s ticket price, you need one or more if statements. You can structure the conditions in many ways, and I chose one of these ways for the code in Listing 10-1.

LISTING 10-1 Are You Paying Too Much?

import java.util.Scanner;

class TicketPrice {

public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
int age;
double price = 0.00;

System.out.print("How old are you? ");
age = keyboard.nextInt();

if (age >= 12 && age < 65) {
price = 9.25;
}
if (age < 12 || age >= 65) {
price = 5.25;
}

System.out.print("Please pay $");
System.out.print(price);
System.out.print(". ");
System.out.println("Enjoy the show!");

keyboard.close();
}
}

Several runs of the TicketPrice program (refer to Listing 10-1) are shown in Figure 10-2. (For your viewing pleasure, I’ve copied the runs from Eclipse’s Console view to Windows Notepad.) When you turn 12, you start paying full price. You keep paying the full price until you become 65. At that point, you pay the reduced price again.

image

FIGURE 10-2: Admission prices for Beginning Programming with Java For Dummies: The Movie.

The pivotal part of Listing 10-1 is the lump of if statements in the middle, which are illustrated in Figure 10-3.

  • The first if statement’s condition tests for the regular-price group. Anyone who’s at least 12 years of age and is under 65 belongs in this group.
  • The second if statement’s condition tests for the fringe ages. A person who’s under 12 or is 65 or older belongs in this category.
image

FIGURE 10-3: The meanings of the conditions in Listing 10-1.

tip When you form the opposite of an existing condition, you can often follow the pattern in Listing 10-1. Change >= to <. Change < to >=. Change && to ||.

warning If you change the dollar amounts in Listing 10-1, you can get into trouble. For example, with the statement price = 5.00, the program displays Please pay $5.0. Enjoy the show! This happens because Java doesn’t store the two zeros to the right of the decimal point (and Java doesn’t know or care that 5.00 is a dollar amount). To fix this kind of thing, see the discussion of NumberFormat.getCurrencyInstance in Chapter 18.

When to initialize?

Take a look at Listing 10-1 and notice the price variable’s initialization:

double price = 0.00;

This line declares the price variable and sets the variable’s starting value to 0.00. When I omit this initialization, I get an error message:

The local variable price may not have been initialized

What’s the deal here? I don’t initialize the age variable, but the compiler doesn’t complain about that. Why is the compiler fussing over the price variable?

The answer is in the placement of the code’s assignment statements. Consider the following two facts:

  • The statement that assigns a value to the age variable (age = keyboard.nextInt()) isn’t inside an if statement.

    That assignment statement always gets executed, and (as long as nothing extraordinary happens) the variable age is sure to be assigned a value.

  • Both statements that assign a value to the price variable (price = 9.25 and price = 5.25) are inside if statements.

    If you look at Figure 10-3, you see that every age group is covered. No one shows up at the ticket counter with an age that forces both if conditions to be false. So, whenever you run the TicketPrice program, either the first or the second price assignment is executed.

    The problem is that the compiler isn’t smart enough to check all of this. The compiler just sees the structure in Figure 10-4 and becomes scared that the computer won’t take either of the true detours.

    If (for some unforeseen reason) both of the if statements’ conditions are false, then the variable price isn’t assigned a value. So without an initialization, price has no value. (More precisely, price has no value that’s intentionally given to it in the code.)

    Eventually, the computer reaches the System.out.print(price) statement. It can’t display price unless price has a meaningful value. At that point, the compiler throws up its virtual hands in disgust.

image

FIGURE 10-4: The choices in Listing 10-1.

More and more conditions

Last night I had a delicious meal at the neighborhood burger joint. As part of a promotion, I got a discount coupon along with the meal. The coupon is good for $2.00 off the price of a ticket at the local movie theater.

To make use of the coupon in the TicketPrice program, I have to tweak the code in Listing 10-1. The revised code is in Listing 10-2. In Figure 10-5, I take that new code around the block a few times.

image

FIGURE 10-5: Running the code in Listing 10-2.

LISTING 10-2 Do You Have a Coupon?

import java.util.Scanner;

class TicketPriceWithDiscount {

public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
int age;
double price = 0.00;
char reply;

System.out.print("How old are you? ");
age = keyboard.nextInt();

System.out.print("Have a coupon? (Y/N) ");
reply = keyboard.findWithinHorizon(".", 0).charAt(0);

if (age >= 12 && age < 65) {
price = 9.25;
}
if (age < 12 || age >= 65) {
price = 5.25;
}

if (reply == ’Y’ || reply == ’y’) {
price -= 2.00;
}
if (reply != ’Y’ && reply != ’y’ && reply!=’N’ && reply!=’n’) {
System.out.println("Huh?");
}

System.out.print("Please pay $");
System.out.print(price);
System.out.print(". ");
System.out.println("Enjoy the show!");

keyboard.close();
}
}

Listing 10-2 has two if statements whose conditions involve characters:

  • In the first such statement, the computer checks to see whether the reply variable stores the letter Y or the letter y. If either is the case, it subtracts 2.00 from the price. (For information on operators like -=, see Chapter 7.)
  • The second such statement has a hefty condition. The condition tests to see whether the reply variable stores any reasonable value at all. If the reply isn’t Y, and isn’t y, and isn’t N, and isn’t n, the computer expresses its concern by displaying, “Huh?” (As a paying customer, the word Huh? on the automated ticket teller’s screen will certainly get your attention.)

tip When you create a big multipart condition, you always have several ways to think about the condition. For example, you can rewrite the last condition in Listing 10-2 as if (!(reply == ’Y’ || reply == ’y’ || reply == ’N’ || reply == ’n’)). “If it’s not the case that the reply is either Y, y, N, or n, then display ‘Huh?’” So which way of writing the condition is better — the way I do it in Listing 10-2 or the way I do it in this tip? It depends on your taste. Whichever makes the logic easier for you to understand is the better way.

Using boolean variables

No matter how good a program is, you can always make it a little bit better. Take the code in Listing 10-2. Does the forest of if statements make you nervous? Do you slow to a crawl when you read each condition? Wouldn’t it be nice if you could glance at a condition and make sense of it very quickly?

To some extent, you can. If you’re willing to create some additional variables, you can make your code easier to read. Listing 10-3 shows you how.

LISTING 10-3 George Boole Would Be Proud

import java.util.Scanner;

class NicePrice {

public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
int age;
double price = 0.00;
char reply;
boolean isKid, isSenior, hasCoupon, hasNoCoupon;

System.out.print("How old are you? ");
age = keyboard.nextInt();

System.out.print("Have a coupon? (Y/N) ");
reply = keyboard.findWithinHorizon(".", 0).charAt(0);

isKid = age < 12;
isSenior = age >= 65;
hasCoupon = reply == ’Y’ || reply == ’y’;
hasNoCoupon = reply == ’N’ || reply == ’n’;

if (!isKid && !isSenior) {
price = 9.25;
}
if (isKid || isSenior) {
price = 5.25;
}
if (hasCoupon) {
price -= 2.00;
}
if (!hasCoupon && !hasNoCoupon) {
System.out.println("Huh?");
}

System.out.print("Please pay $");
System.out.print(price);
System.out.print(". ");
System.out.println("Enjoy the show!");

keyboard.close();
}
}

Runs of the Listing 10-3 code look like the stuff in Figure 10-5. The only difference between Listings 10-2 and 10-3 is the use of boolean variables. In Listing 10-3, you get past all the less-than signs and double equal signs before the start of any if statements. By the time you encounter the two if statements, the conditions can use simple words — words like isKid, isSenior, and hasCoupon. With all these boolean variables, expressing each if statement’s condition is a snap. You can read more about boolean variables in Chapter 8.

Adding a boolean variable can make your code more manageable. But because some programming languages don’t have boolean variables, many programmers prefer to create if conditions on the fly. That’s why I mix the two techniques (conditions with and without boolean variables) in this book.

Mixing different logical operators together

If you read about Listing 10-2, you know that my local movie theater offers discount coupons. The trouble is, I can’t use a coupon along with any other discount. I tried to convince the ticket taker that I’m under 12 years of age, but he didn’t buy it. When that didn’t work, I tried combining the coupon with the senior citizen discount. That didn’t work, either.

Apparently, the theater uses some software that checks for people like me. It looks something like the code in Listing 10-4. To watch the code run, take a look at Figure 10-6.

image

FIGURE 10-6: Running the code in Listing 10-4.

LISTING 10-4 No Extra Break for Kids or Seniors

import java.util.Scanner;

class CheckAgeForDiscount {

public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
int age;
double price = 0.00;
char reply;

System.out.print("How old are you? ");
age = keyboard.nextInt();

System.out.print("Have a coupon? (Y/N) ");
reply = keyboard.findWithinHorizon(".", 0).charAt(0);

if (age >= 12 && age < 65) {
price = 9.25;
}
if (age < 12 || age >= 65) {
price = 5.25;
}

if ((reply == ’Y’ || reply == ’y’) &&
(age >= 12 && age < 65)) {
price -= 2.00;
}

System.out.print("Please pay $");
System.out.print(price);
System.out.print(". ");
System.out.println("Enjoy the show!");

keyboard.close();
}
}

Listing 10-4 is a lot like its predecessors, Listings 10-1 and 10-2. The big difference is the bolded if statement. This if statement tests two things, and each thing has two parts of its own:

  • Does the customer have a coupon?

    That is, did the customer reply with either Y or y?

  • Is the customer in the regular age group?

    That is, is the customer at least 12 years old and younger than 65?

In Listing 10-4, I join items 1 and 2 using the && operator. I do this because both items (item 1 and item 2) must be true in order for the customer to qualify for the $2.00 discount, as illustrated in Figure 10-7.

image

FIGURE 10-7: Both the reply and the age criteria must be true.

Using parentheses

Listing 10-4 demonstrates something important about conditions. Sometimes, you need parentheses to make a condition work correctly. Take, for example, the following incorrect if statement:

//This code is incorrect:
if (reply == ’Y’ || reply == ’y’ && age >= 12 && age < 65) {
price -= 2.00;
}

Compare this code with the correct code in Listing 10-4. This incorrect code has no parentheses to group reply == ’Y’ with reply == ’y’, or to group age >= 12 with age < 65. The result is the bizarre pair of runs in Figure 10-8.

image

FIGURE 10-8: A capital offense.

In Figure 10-8, notice that the y and Y inputs yield different ticket prices, even though the age is 85 in both runs. This happens because, without parentheses, any && operator gets evaluated before any || operator. (That’s the rule in the Java programming language — evaluate && before ||.) When reply is Y, the condition in the bad if statement takes the following form:

reply == ’Y’ || some-other-stuff-that-does-not-matter

Whenever reply == ’Y’ is true, the whole condition is automatically true, as illustrated in Figure 10-9.

image

FIGURE 10-9: “True or false” makes “true.”

Building a Nest

The year is 1968, and The Prisoner is on TV. In the last episode, the show’s hero meets his nemesis, “Number One.” At first, Number One wears a spooky happy-face/sad-face mask, and when the mask comes off, there’s a monkey mask underneath. To find out what’s behind the monkey mask, you have to rent the series and watch it yourself. But in the meantime, notice the layering: a mask within a mask. You can do the same kind of thing with if statements. This section’s example shows you how.

But first, take a look at Listing 10-4. In that code, the condition age >= 12 && age < 65 is tested twice. Both times, the computer sends the numbers 12 and 65, and the age value through its jumble of circuits; and both times, the computer gets the same answer. This is wasteful, but waste isn’t your only concern.

What if you decide to change the age limit for senior tickets? From now on, no one under 100 gets a senior discount. You fish through the code and see the first age >= 12 && age < 65 test. You change 65 to 100, pat yourself on the back, and go home. The problem is, you’ve changed one of the two age >= 12 && age < 65 tests, but you haven’t changed the other. Wouldn’t it be better to keep all the age >= 12 && age < 65 testing in just one place?

Listing 10-5 comes to the rescue. In Listing 10-5, I smoosh all my if statements together into one big glob. The code is dense, but it gets the job done nicely.

LISTING 10-5 Nested if Statements

import java.util.Scanner;

class AnotherAgeCheck {

public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
int age;
double price = 0.00;
char reply;

System.out.print("How old are you? ");
age = keyboard.nextInt();

System.out.print("Have a coupon? (Y/N) ");
reply = keyboard.findWithinHorizon(".", 0).charAt(0);

if (age >= 12 && age < 65) {
price = 9.25;
if (reply == ’Y’ || reply == ’y’) {
price -= 2.00;
}
} else {
price = 5.25;
}

System.out.print("Please pay $");
System.out.print(price);
System.out.print(". ");
System.out.println("Enjoy the show!");

keyboard.close();
}
}

Nested if statements

A run of the code in Listing 10-5 looks identical to a run for Listing 10-4. You can see several runs in Figure 10-6. The main idea in Listing 10-5 is to put an if statement inside another if statement. After all, Chapter 9 says that an if statement can take the following form:

if (Condition) {
SomeStatements
} else {
OtherStatements
}

Who says SomeStatements can’t contain an if statement? For that matter, OtherStatements can also contain an if statement. And, yes, you can create an if statement within an if statement within an if statement. There’s no predefined limit on the number of if statements that you can have.

if (age >= 12 && age < 65) {
price = 9.25;
if (reply == ’Y’ || reply == ’y’) {
if (isSpecialFeature) {
price -= 1.00;
} else {
price -= 2.00;
}
}
} else {
price = 5.25;
}

When you put one if statement inside another, you create nested if statements. Nested statements aren’t difficult to write, as long as you take things slowly and keep a clear picture of the code’s flow in your mind. If it helps, draw yourself a diagram like the one shown in Figure 10-10.

warning When you nest statements, you must be compulsive about the use of indentation and braces. (See Figure 10-11.) When code has misleading indentation, no one (not even the programmer who wrote the code) can figure out how the code works. A nested statement with sloppy indentation is a programmer’s nightmare.

image

FIGURE 10-11: Be careful about adding the proper indentation and braces.

Cascading if statements

Here’s a riddle: 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 listed first. (On the computer screen, the winner’s score is displayed above the loser’s score.) What happens when the scores are tied?

Do you give up? The answer is, there’s no right answer. What happens depends on the way you write the program. Take a look at Listing 9-4, in Chapter 9. When the scores are equal, the condition hankees > socks is false. So the program’s flow of execution drops down to the else clause. That clause displays the Socks score first and the Hankees score second. (Refer to Figure 9-7, in Chapter 9.)

The program doesn’t have to work this way. If I take Listing 9-4 and change hankees > socks to hankees >= socks, then, in case of a tie, the Hankees score comes first.

Suppose that you want a bit more control. When the scores are equal, you want to see an It’s a tie message. To do this, think in terms of a three-pronged fork. You have a prong for a Hankees win, another prong for a Socks win, and a third prong for a tie. You can write this code in several different ways, but one way that makes lots of sense is in Listing 10-6. For three runs of the code in Listing 10-6, see Figure 10-12.

image

FIGURE 10-12: Go, team, go!

LISTING 10-6 In Case of a Tie …

import java.util.Scanner;
import static java.lang.System.out;

class WinLoseOrTie {

public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
int hankees, socks;

out.print("Hankees and Socks scores? ");
hankees = keyboard.nextInt();
socks = keyboard.nextInt();
out.println();

if (hankees > socks) {
out.println("Hankees win…");
out.print("Hankees: ");
out.println(hankees);
out.print("Socks: ");
out.println(socks);
} else if (socks > hankees) {
out.println("Socks win…");
out.print("Socks: ");
out.println(socks);
out.print("Hankees: ");
out.println(hankees);
} else {
out.println("It’s a tie…");
out.print("Hankees: ");
out.println(hankees);
out.print("Socks: ");
out.println(socks);
}

keyboard.close();
}
}

Listing 10-6 illustrates a way of thinking about a problem. You have one question with more than two answers. (In this section’s baseball problem, the question is “Who wins?” and the answers are “Hankees,” “Socks,” or “Neither.”) The problem begs for an if statement, but an if statement has only two branches — the true branch and the false branch. So you combine alternatives to form cascading if statements.

In Listing 10-6, the format for the cascading if statements is

if (Condition1) {
SomeStatements
} else if (Condition2) {
OtherStatements
} else {
EvenMoreStatements
}

In general, you can use else if as many times as you want:

if (hankeesWin) {
out.println("Hankees win…");
out.print("Hankees: ");
out.println(hankees);
out.print("Socks: ");
out.println(socks);
} else if (socksWin) {
out.println("Socks win…");
out.print("Socks: ");
out.println(socks);
out.print("Hankees: ");
out.println(hankees);
} else if (isATie) {
out.println("It’s a tie…");
out.print("Hankees: ");
out.println(hankees);
out.print("Socks: ");
out.println(socks);
} else if (gameCancelled) {
out.println("Sorry, sports fans.");
} else {
out.println("The game isn’t over yet.");
}

Nothing is special about cascading if statements. This isn’t a new programming language feature. Cascading if statements take advantage of a loophole in Java — a loophole about omitting curly braces in certain circumstances. Other than that, cascading if statements just give you a new way to think about decisions within your code.

Note: Listing 10-6 uses a static import declaration to avoid needless repetition of the words System.out. To read a little bit about the static import declaration (along with an apology for my not explaining this concept more thoroughly), see Chapter 9. Then to get the real story on static import declarations, see Chapter 18.

Enumerating the Possibilities

Chapter 8 describes Java’s boolean type — the type with only two values (true and false). The boolean type is very handy, but sometimes you need more values. After all, a traffic light’s values can be green, yellow, or red. A playing card’s suit can be spade, club, heart, or diamond. And a weekday can be Monday, Tuesday, Wednesday, Thursday, or Friday.

Life is filled with small sets of possibilities, and Java has a feature that can reflect these possibilities. The feature is called an enum type. It’s available from Java version 5.0 onward.

Creating an enum type

The story in Listing 10-6 has three possible endings — the Hankees win, the Socks win, or the game is tied. You can represent the possibilities with the following line of Java code:

enum WhoWins {home, visitor, neither}

This week’s game is played at Hankeeville’s SnitSoft Stadium, so the value home represents a win for the Hankees, and the value visitor represents a win for the Socks.

One of the goals in computer programming is for each program’s structure to mirror whatever problem the program solves. When a program reminds you of its underlying problem, the program is easy to understand and inexpensive to maintain. For example, a program to tabulate customer accounts should use names like customer and account. And a program that deals with three possible outcomes (home wins, visitor wins, and tie) should have a variable with three possible values. The line enum WhoWins {home, visitor, neither} creates a type to store three values.

The WhoWins type is called an enum type. Think of the new WhoWins type as a boolean on steroids. Instead of two values (true and false), the WhoWins type has three values (home, visitor, and neither). You can create a variable of type WhoWins:

WhoWins who;

and then assign a value to the new variable:

who = WhoWins.home;

In the next section, I put the WhoWins type to good use.

Using an enum type

Listing 10-7 shows you how to use the brand-new WhoWins type.

LISTING 10-7 Proud Winners and Sore Losers

import java.util.Scanner;
import static java.lang.System.out;

class Scoreboard {

enum WhoWins {home, visitor, neither}

public static void main(String args[]) {
Scanner keyboard = new Scanner(System.in);
int hankees, socks;
WhoWins who;

out.print("Hankees and Socks scores? ");
hankees = keyboard.nextInt();
socks = keyboard.nextInt();
out.println();

if (hankees > socks) {
who = WhoWins.home;
out.println("The Hankees win :-)");
} else if (socks > hankees) {
who = WhoWins.visitor;
out.println("The Socks win :-(");
} else {
who = WhoWins.neither;
out.println("It’s a tie :-|");
}

out.println();
out.println("Today’s game is brought to you by");
out.println("SnitSoft, the number one software");
out.println("vendor in the Hankeeville area.");
out.println("SnitSoft is featured proudly in");
out.println("Chapter 6. And remember, four out");
out.println("of five doctors recommend");
out.println("SnitSoft to their patients.");
out.println();

if (who == WhoWins.home) {
out.println("We beat ’em good. Didn’t we?");
}

if (who == WhoWins.visitor) {
out.println("The umpire made an unfair call.");
}

if (who == WhoWins.neither) {
out.println("The game goes into overtime.");
}

keyboard.close();
}
}

Three runs of the program in Listing 10-7 are pictured in Figure 10-13.

image

FIGURE 10-13: Joy in Hankeeville?

Here’s what happens in Listing 10-7:

  • I create a variable to store values of type WhoWins.

    Just as the line

    double amount;

  • declares amount to store double values (values like 5.95 and 30.95), the line

    WhoWins who;

    declares who to store WhoWins values (values like home, visitor, and neither).

  • I assign a value to the who variable.

    I execute one of the

    who = WhoWins.something;

    assignment statements. The statement that I execute depends on the outcome of the if statement’s hankees > socks comparison.

    Notice that I refer to each of the WhoWins values in Listing 10-7. I write WhoWins.home, WhoWins.visitor, or WhoWins.neither. If I forget the WhoWins prefix and type

    who = home; //This assignment doesn’t work!

    the compiler gives me a home cannot be resolved to a variable error message. That’s just the way enum types work.

  • I compare the variable’s value with each of the WhoWins values.

    In one if statement, I check the who == WhoWins.home condition. In the remaining two if statements, I check for the other WhoWins values.

Near the end of Listing 10-7, I could have done without enum values. I could have tested things like hankees > socks a second time:

if (hankees > socks) {
out.println("The Hankees win :-)");
}

// And later in the program …

if (hankees > socks) {
out.println("We beat ’em good. Didn’t we?");
}

But that tactic would be clumsy. In a more complicated program, I may end up checking hankees > socks a dozen times. It would be like asking the same question over and over again.

Instead of repeatedly checking the hankees > socks condition, I store the game’s outcome as an enum value. Then I check the enum value as many times as I want. That’s a tidy way to solve the repeated checking problem.

tryitout It’s okay to read about Java, but it’s even better if you work with Java. Here are some things you can do to flex your Java muscles:

MYSTERIOUS WAYS

Explain why the following code always displays The first is smaller, no matter what numbers the user types. For example, if the user types 7 and then 5, the program displays The first is smaller:

int firstNumber = keyboard.nextInt();
int secondNumber = keyboard.nextInt();
boolean firstSmaller = firstNumber < secondNumber;

if (firstSmaller = true) {
System.out.println("The first is smaller.");
}

WHAT KIND OF NUMBER?

Write a program that reads a number from the keyboard and displays one of the words positive, negative, or zero to describe that number. Use cascading if statements.

APPROACHING A TRAFFIC SIGNAL

Your driver’s handbook says, “When approaching a green light, proceed through the intersection unless it’s unsafe to do so, or unless a police officer directs you to do otherwise.”

Write a program that asks the user three questions:

  • Are you approaching a green light?
  • Is it safe to proceed through the intersection?
  • Is a police officer directing you not to proceed?

In response to each question, the user replies Y or N. Based on the three replies, the program displays either Go or Stop.

Needless to say, you shouldn’t run this program while you drive a vehicle.

“YES” AND “YES” AGAIN

Modify the “Approaching a traffic signal” program so that the program allows the user to reply “yes” with either an uppercase letter Y or a lowercase letter y.

RED OR YELLOW LIGHT

Modify the “Approaching a traffic signal” program so that the program asks What color is the traffic light? (G/Y/R). When the user replies Y or R, and either it’s not safe to proceed or an office is directing drivers not to proceed, the program displays Stop. Otherwise, the program doesn’t display anything.

WHAT? ANOTHER TRAFFIC SIGNAL PROGRAM?

You can use System.out.println to display an enum value. For example, in Listing 10-7, if you add the statement

System.out.println(who);

to the end of the main method, the program displays one of the words home, visitor, or neither. Try this by creating an enum named Color with values green, yellow, and red. Write a program that asks What color is the traffic light? (G/Y/R). Use the user’s response to assign one of the values Color.green, Color.yellow, or Color.red to a variable named signal. Use System.out.println to display the value of the signal variable.

BUYING 3D GLASSES

My local movie theater charges an extra three dollars for a movie showing in 3D. (The theater makes me buy a new pair of 3D glasses. I can’t bring the pair that I bought the last time I saw a 3D movie.) Modify the code in Listing 10-5 so that the program asks How many dimensions: 2 or 3? For a 3D movie, the program adds three dollars to the price of admission. (Note: The old Twilight Zone television series began with narrator Rod Serling talking about a fifth dimension. I wonder what I’d have to pay nowadays to see the Twilight Zone in my local movie theater!)

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

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