The programs in the previous chapters do pretty much the same thing every time, regardless of the input. For more-complex computations, programs usually react to inputs, check for certain conditions, and generate applicable results. This chapter introduces Java language features for expressing logic and making decisions.
Java has six relational operators that test the relationship between two values (e.g., whether they are equal, or whether one is greater than the other). The following expressions show how they are used:
x
==
y
// x is equal to y
x
!=
y
// x is not equal to y
x
>
y
// x is greater than y
x
<
y
// x is less than y
x
>=
y
// x is greater than or equal to y
x
<=
y
// x is less than or equal to y
You are probably familiar with these operators, but notice how Java is different from mathematical symbols like , ≠, and ≥. A common error is to use a single =
instead of a double ==
when comparing values. Remember that =
is the assignment operator, and ==
is a relational operator. Also, the operators =<
and =>
do not exist.
To write useful programs, we almost always need to check conditions and react accordingly. Conditional statements give us this ability. The simplest conditional statement in Java is the if
statement:
if
(
x
>
0
)
{
System
.
out
.
println
(
"x is positive"
);
}
A second form of conditional statement has two possibilities, indicated by if
and else
. The possibilities are called branches, and the condition determines which branch gets executed:
if
(
x
%
2
==
0
)
{
System
.
out
.
println
(
"x is even"
);
}
else
{
System
.
out
.
println
(
"x is odd"
);
}
if
(
x
%
2
==
0
)
System
.
out
.
println
(
"x is even"
);
else
System
.
out
.
println
(
"x is odd"
);
if
(
x
>
0
)
System
.
out
.
println
(
"x is positive"
);
System
.
out
.
println
(
"x is not zero"
);
if
(
x
>
0
)
{
System
.
out
.
println
(
"x is positive"
);
}
System
.
out
.
println
(
"x is not zero"
);
int
x
=
1
;
if
(
x
%
2
==
0
);
{
// incorrect semicolon
System
.
out
.
println
(
"x is even"
);
}
int
x
=
1
;
if
(
x
%
2
==
0
)
;
// empty statement
{
System
.
out
.
println
(
"x is even"
);
}
The compiler won’t complain if you omit optional braces or write empty statements. Doing so is allowed by the Java language, but it often results in bugs that are difficult to find. Development tools like Checkstyle (see “Running Checkstyle”) can warn you about these and other kinds of programming mistakes.
if
(
x
>
0
)
{
System
.
out
.
println
(
"x is positive"
);
}
else
if
(
x
<
0
)
{
System
.
out
.
println
(
"x is negative"
);
}
else
{
System
.
out
.
println
(
"x is zero"
);
}
if
(
x
>
0
)
{
System
.
out
.
println
(
"x is positive"
);
}
else
{
if
(
x
<
0
)
{
System
.
out
.
println
(
"x is negative"
);
}
else
{
System
.
out
.
println
(
"x is zero"
);
}
}
if
(
number
==
1
)
{
word
=
"one"
;
}
else
if
(
number
==
2
)
{
word
=
"two"
;
}
else
if
(
number
==
3
)
{
word
=
"three"
;
}
else
{
word
=
"unknown"
;
}
This chain could go on and on, especially for banking programs that write numbers in long form (e.g., “one hundred twenty-three and 45/100 dollars”). An alternative way to evaluate many possible values of an expression is to use a switch
statement:
switch
(
number
)
{
case
1
:
word
=
"one"
;
break
;
case
2
:
word
=
"two"
;
break
;
case
3
:
word
=
"three"
;
break
;
default
:
word
=
"unknown"
;
break
;
}
switch
(
food
)
{
case
"apple"
:
case
"banana"
:
case
"cherry"
:
System
.
out
.
println
(
"Fruit!"
);
break
;
case
"asparagus"
:
case
"broccoli"
:
case
"carrot"
:
System
.
out
.
println
(
"Vegetable!"
);
break
;
}
In addition to the relational operators, Java also has three logical operators: &&
, ||
, and !
, which respectively stand for and, or, and not. The results of these operators are similar to their meanings in English.
For example, x > 0 && x < 10
is true when x
is both greater than 0 and less than 10.
if
(
x
==
0
)
{
if
(
y
==
0
)
{
System
.
out
.
println
(
"Both x and y are zero"
);
}
}
// combined
if
(
x
==
0
&&
y
==
0
)
{
System
.
out
.
println
(
"Both x and y are zero"
);
}
if
(
x
==
0
)
{
System
.
out
.
println
(
"Either x or y is zero"
);
}
else
if
(
y
==
0
)
{
System
.
out
.
println
(
"Either x or y is zero"
);
}
// combined
if
(
x
==
0
||
y
==
0
)
{
System
.
out
.
println
(
"Either x or y is zero"
);
}
To store a true
or false
value, you need a boolean
variable. You can declare and assign them like other variables. In this example, the first line is a variable declaration, the second is an assignment, and the third is both:
boolean
flag
;
flag
=
true
;
boolean
testResult
=
false
;
Since relational and logical operators evaluate to a boolean
value, you can store the result of a comparison in a variable:
boolean
evenFlag
=
(
n
%
2
==
0
);
// true if n is even
boolean
positiveFlag
=
(
x
>
0
);
// true if x is positive
You can use flag variables as part of a conditional statement:
if
(
evenFlag
)
{
System
.
out
.
println
(
"n was even when I checked it"
);
}
if
(!
evenFlag
)
{
System
.
out
.
println
(
"n was odd when I checked it"
);
}
Methods can return boolean
values, just like any other type, which is often convenient for hiding tests inside methods. For example:
public
static
boolean
isSingleDigit
(
int
x
)
{
if
(
x
>
-
10
&&
x
<
10
)
{
return
true
;
}
else
{
return
false
;
}
}
public
static
boolean
isSingleDigit
(
int
x
)
{
return
x
>
-
10
&&
x
<
10
;
}
In main
, you can invoke the method in the usual ways:
System
.
out
.
println
(
isSingleDigit
(
2
));
boolean
bigFlag
=
!
isSingleDigit
(
17
);
Conditional statements often invoke boolean
methods and use the result as the condition:
if
(
isSingleDigit
(
z
))
{
System
.
out
.
println
(
"z is small"
);
}
else
{
System
.
out
.
println
(
"z is big"
);
}
One of the most important tasks in any computer program is to validate input from the user. People often make mistakes while typing, especially on smartphones, and incorrect inputs may cause your program to fail.
Consider this simple program that prompts the user for a number and computes its logarithm:
Scanner
in
=
new
Scanner
(
System
.
in
);
System
.
out
.
(
"Enter a number: "
);
double
x
=
in
.
nextDouble
();
double
y
=
Math
.
log
(
x
);
System
.
out
.
println
(
"The log is "
+
y
);
if
(
x
>
0
)
{
double
y
=
Math
.
log
(
x
);
System
.
out
.
println
(
"The log is "
+
y
);
}
else
{
System
.
out
.
println
(
"The log is undefined"
);
}
The output is better now, but there is another problem. What if the user doesn’t enter a number at all? What would happen if they typed the word hello
, either by accident or on purpose?
Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor(Scanner.java:864) at java.util.Scanner.next(Scanner.java:1485) at java.util.Scanner.nextDouble(Scanner.java:2413) at Logarithm.main(Logarithm.java:8)
If the user inputs a String
when we expect a double
, Java reports an input mismatch
exception. We can prevent this run-time error from happening by testing the input first.
if
(!
in
.
hasNextDouble
())
{
String
word
=
in
.
next
();
System
.
err
.
println
(
word
+
"is not a number"
);
}
import
java.util.Scanner
;
/**
* Demonstrates input validation using if statements.
*/
public
class
Logarithm
{
public
static
void
main
(
String
[]
args
)
{
// prompt for input
Scanner
in
=
new
Scanner
(
System
.
in
);
System
.
out
.
(
"Enter a number: "
);
// check the format
if
(!
in
.
hasNextDouble
())
{
String
word
=
in
.
next
();
System
.
err
.
println
(
word
+
" is not a number"
);
return
;
}
// check the range
double
x
=
in
.
nextDouble
();
if
(
x
>
0
)
{
double
y
=
Math
.
log
(
x
);
System
.
out
.
println
(
"The log is "
+
y
);
}
else
{
System
.
out
.
println
(
"The log is undefined"
);
}
}
}
Notice that the return
statement allows you to exit a method before you reach the end of it. Returning from main
terminates the program.
What started as five lines of code at the beginning of “Validating Input” is now a 30-line program. Making programs robust (and secure) often requires a lot of additional checking, as shown in this example.
A statement that uses a condition to determine which statements to execute.
A sequence of statements, surrounded by braces, that generally runs as the result of a condition.
A way of joining several conditional statements in sequence.
Putting a conditional statement inside one or both branches of another conditional statement.
An operator that combines boolean values and produces a boolean value.
A way of evaluating logical operators that evaluates the second operand only if necessary.
Mathematical rules that show how to negate a logical expression.
A variable (usually boolean
) that represents a condition or status.
To confirm that an input value is of the correct type and within the expected range.
A special floating-point value that stands for not a number.
The code for this chapter is in the ch05 directory of ThinkJavaCode2. See “Using the Code Examples” for instructions on downloading the repository. Before you start the exercises, we recommend that you compile and run the examples.
If you have not already read “Running Checkstyle”, now might be a good time. It describes Checkstyle, a tool that analyzes many aspects of your source code.
Rewrite the following code by using a single if
statement:
if
(
x
>
0
)
{
if
(
x
<
10
)
{
System
.
out
.
println
(
"positive single digit number."
);
}
}
Now that we have conditional statements, we can get back to the Guess My Number game from Exercise 3-4.
You should already have a program that chooses a random number, prompts the user to guess it, and displays the difference between the guess and the chosen number.
By adding a small amount of code at a time and testing as you go, modify the program so it tells the user whether the guess is too high or too low, and then prompts the user for another guess.
The program should continue until the user gets it right or guesses incorrectly three times. If the user guesses the correct number, display a message and terminate the program.
Fermat’s Last Theorem says that there are no integers a, b, c, and n such that , except when .
Write a program named Fermat.java
that inputs four integers (a
, b
, c
, and n
) and checks to see if Fermat’s theorem holds. If n is greater than 2 and , the program should display Holy smokes, Fermat was wrong!
Otherwise, the program should display “No, that doesn’t work.”
Hint: You might want to use Math.pow
.
Using the following variables, evaluate the logic expressions in the table that follows. Write your answers as true, false, or error.
boolean
yes
=
true
;
boolean
no
=
false
;
int
loVal
=
-
999
;
int
hiVal
=
999
;
double
grade
=
87.5
;
double
amount
=
50.0
;
String
hello
=
"world"
;
Expression | Result |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
What is the output of the following program? Determine the answer without using a computer. The purpose of this exercise is to make sure you understand logical operators and the flow of execution through methods.
public
static
void
main
(
String
[]
args
)
{
boolean
flag1
=
isHoopy
(
202
);
boolean
flag2
=
isFrabjuous
(
202
);
System
.
out
.
println
(
flag1
);
System
.
out
.
println
(
flag2
);
if
(
flag1
&&
flag2
)
{
System
.
out
.
println
(
"ping!"
);
}
if
(
flag1
||
flag2
)
{
System
.
out
.
println
(
"pong!"
);
}
}
public
static
boolean
isHoopy
(
int
x
)
{
boolean
hoopyFlag
;
if
(
x
%
2
==
0
)
{
hoopyFlag
=
true
;
}
else
{
hoopyFlag
=
false
;
}
return
hoopyFlag
;
}
public
static
boolean
isFrabjuous
(
int
x
)
{
boolean
frabjuousFlag
;
if
(
x
>
0
)
{
frabjuousFlag
=
true
;
}
else
{
frabjuousFlag
=
false
;
}
return
frabjuousFlag
;
}
Write a program named Quadratic.java
that finds the roots of using the quadratic formula:
Prompt the user to input integers for a, b, and c. Compute the two solutions for x, and display the results.
Your program should be able to handle inputs for which there is only one or no solution. Specifically, it should not divide by zero or take the square root of a negative number.
Be sure to validate all inputs. The user should never see an input mismatch exception. Display specific error messages that include the invalid input.
If you are given three sticks, you may or may not be able to arrange them in a triangle. For example, if one of the sticks is 12 inches long and the other two are 1 inch long, you will not be able to get the short sticks to meet in the middle. For any three lengths, there is a simple test to see if it is possible to form a triangle:
If any of the three lengths is greater than the sum of the other two, you cannot form a triangle.
Write a program named Triangle.java
that inputs three integers, and then outputs whether you can (or cannot) form a triangle from the given lengths. Reuse your code from the previous exercise to validate the inputs. Display an error if any of the lengths are negative or zero.