Control Flow Statements
The If-Then Statement
The if-then
statement is the most basic of all the control flow statements. It tells your program to execute a certain section of code only if a particular test evaluates to true
. For example, the Bicycle
class could allow the brakes to decrease the bicycle's speed only if the bicycle is already in motion. One possible implementation of the applyBrakes()
method could be as follows:
void applyBrakes() {
// the "if" clause: bicycle must be moving
if (isMoving){
// the "then" clause: decrease current speed
currentSpeed--;
}
}
If this test evaluates to false
(meaning that the bicycle is not in motion), control jumps to the end of the if-then
statement.
In addition, the opening and closing braces are optional, provided that the "then" clause contains only one statement:
void applyBrakes() {
// same as above, but without braces
if (isMoving)
currentSpeed--;
}
Deciding when to omit the braces is a matter of personal taste. Omitting them can make the code more brittle. If a second statement is later added to the "then" clause, a common mistake would be forgetting to add the newly required braces. The compiler cannot catch this sort of error; you will just get the wrong results.
The If-Then-Else Statement
The if-then-else
statement provides a secondary path of execution when an "if" clause evaluates to false
. You could use an if-then-else
statement in the applyBrakes()
method to take some action if the brakes are applied when the bicycle is not in motion. In this case, the action is to simply print an error message stating that the bicycle has already stopped.
void applyBrakes() {
if (isMoving) {
currentSpeed--;
} else {
System.err.println("The bicycle has already stopped!");
}
}
The following program, IfElseDemo
, assigns a grade based on the value of a test score: an A for a score of 90% or above, a B for a score of 80% or above, and so on.
class IfElseDemo {
public static void main(String[] args) {
int testscore = 76;
char grade;
if (testscore >= 90) {
grade = 'A';
} else if (testscore >= 80) {
grade = 'B';
} else if (testscore >= 70) {
grade = 'C';
} else if (testscore >= 60) {
grade = 'D';
} else {
grade = 'F';
}
System.out.println("Grade = " + grade);
}
}
The output from the program is:
Grade = C
You may have noticed that the value of testscore
can satisfy more than one expression in the compound statement: 76 >= 70
and 76 >= 60
. However, once a condition is satisfied, the appropriate statements are executed (grade = 'C';
) and the remaining conditions are not evaluated.
The While and Do-while Statements
The while
statement continually executes a block of statements while a particular condition is true
. Its syntax can be expressed as:
while (expression) {
statement(s)
}
The while
statement evaluates expression, which must return a boolean
value. If the expression evaluates to true
, the while
statement executes the statement(s)
in the while block. The while
statement continues testing the expression and executing its block until the expression evaluates to false
. Using the while
statement to print the values from 1 through 10 can be accomplished as in the following WhileDemo
program:
class WhileDemo {
public static void main(String[] args){
int count = 1;
while (count < 11) {
System.out.println("Count is: " + count);
count++;
}
}
}
You can implement an infinite loop using the while
statement as follows:
while (true){
// your code goes here
}
The Java programming language also provides a do-while
statement, which can be expressed as follows:
do {
statement(s)
} while (expression);
The difference between do-while
and while
is that do-while
evaluates its expression at the bottom of the loop instead of the top. Therefore, the statements within the do
block are always executed at least once, as shown in the following DoWhileDemo
program:
class DoWhileDemo {
public static void main(String[] args){
int count = 1;
do {
System.out.println("Count is: " + count);
count++;
} while (count < 11);
}
}
The For Statement
The for
statement provides a compact way to iterate over a range of values. Programmers often refer to it as the "for loop" because of the way in which it repeatedly loops until a particular condition is satisfied. The general form of the for
statement can be expressed as follows:
for (initialization; termination; increment) {
statement(s)
}
When using this version of the for statement, keep in mind that:
- The initialization expression initializes the loop; it is executed once, as the loop begins.
- When the termination expression evaluates to
false
, the loop terminates. - The increment expression is invoked after each iteration through the loop; it is perfectly acceptable for this expression to increment or decrement a value.
The following program, ForDemo
, uses the general form of the for
statement to print the numbers 1 through 10 to standard output:
class ForDemo {
public static void main(String[] args){
for(int i = 1; i < 11; i++){
System.out.println("Count is: " + i);
}
}
}
The output of this program is:
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10
Notice how the code declares a variable within the initialization expression. The scope of this variable extends from its declaration to the end of the block governed by the for
statement, so it can be used in the termination and increment expressions as well. If the variable that controls a for
statement is not needed outside of the loop, it is best to declare the variable in the initialization expression. The names i
, j
, and k
are often used to control for
loops; declaring them within the initialization expression limits their life span and reduces errors.
The three expressions of the for
loop are optional; an infinite loop can be created as follows:
// infinite loop
for ( ; ; ) {
// your code goes here
}
The for
statement also has another form designed for iteration through Collections and arrays. This form is sometimes referred to as the enhanced for statement, and can be used to make your loops more compact and easy to read. To demonstrate, consider the following array, which holds the numbers 1 through 10:
int[] numbers = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
The following program, EnhancedForDemo
, uses the enhanced for to loop through the array:
class EnhancedForDemo {
public static void main(String[] args){
int[] numbers =
{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (int item : numbers) {
System.out.println("Count is: " + item);
}
}
}
In this example, the variable item
holds the current value from the numbers array. The output from this program is the same as before:
Count is: 1
Count is: 2
Count is: 3
Count is: 4
Count is: 5
Count is: 6
Count is: 7
Count is: 8
Count is: 9
Count is: 10
We recommend using this form of the for
statement instead of the general form whenever possible.
The Break Statement
The break
statement has two forms: labeled and unlabeled. You saw the unlabeled form in the previous discussion of the switch
statement. You can also use an unlabeled break
to terminate a for
, while
, or do-while
loop, as shown in the following BreakDemo
program:
class BreakDemo {
public static void main(String[] args) {
int[] arrayOfInts =
{ 32, 87, 3, 589,
12, 1076, 2000,
8, 622, 127 };
int searchfor = 12;
int i;
boolean foundIt = false;
for (i = 0; i < arrayOfInts.length; i++) {
if (arrayOfInts[i] == searchfor) {
foundIt = true;
break;
}
}
if (foundIt) {
System.out.println("Found " + searchfor + " at index " + i);
} else {
System.out.println(searchfor + " not in the array");
}
}
}
This program searches for the number 12 in an array. The break
statement, terminates the for
loop when that value is found. Control flow then transfers to the statement after the for
loop. This program's output is:
Found 12 at index 4
An unlabeled break
statement terminates the innermost switch
, for
, while
, or do-while
statement, but a labeled break
terminates an outer statement. The following program, BreakWithLabelDemo
, is similar to the previous program, but uses nested for
loops to search for a value in a two-dimensional array. When the value is found, a labeled break
terminates the outer for
loop (labeled "search"):
class BreakWithLabelDemo {
public static void main(String[] args) {
int[][] arrayOfInts = {
{ 32, 87, 3, 589 },
{ 12, 1076, 2000, 8 },
{ 622, 127, 77, 955 }
};
int searchfor = 12;
int i;
int j = 0;
boolean foundIt = false;
search:
for (i = 0; i < arrayOfInts.length; i++) {
for (j = 0; j < arrayOfInts[i].length;
j++) {
if (arrayOfInts[i][j] == searchfor) {
foundIt = true;
break search;
}
}
}
if (foundIt) {
System.out.println("Found " + searchfor + " at " + i + ", " + j);
} else {
System.out.println(searchfor + " not in the array");
}
}
}
This is the output of the program.
Found 12 at 1, 0
The break
statement terminates the labeled statement; it does not transfer the flow of control to the label. Control flow is transferred to the statement immediately following the labeled (terminated) statement.
The Continue Statement
The continue
statement skips the current iteration of a for
, while
, or do-while
loop. The unlabeled form skips to the end of the innermost loop's body and evaluates the boolean expression that controls the loop. The following program, ContinueDemo
, steps through a String
, counting the occurrences of the letter p
. If the current character is not a p
, the continue
statement skips the rest of the loop and proceeds to the next character. If it is a p
, the program increments the letter count.
class ContinueDemo {
public static void main(String[] args) {
String searchMe = "peter piper picked a " + "peck of pickled peppers";
int max = searchMe.length();
int numPs = 0;
for (int i = 0; i < max; i++) {
// interested only in p's
if (searchMe.charAt(i) != 'p')
continue;
// process p's
numPs++;
}
System.out.println("Found " + numPs + " p's in the string.");
}
}
Here is the output of this program:
Found 9 p's in the string.
To see this effect more clearly, try removing the continue
statement and recompiling. When you run the program again, the count will be wrong, saying that it found 35 p
's instead of 9.
A labeled continue
statement skips the current iteration of an outer loop marked with the given label. The following example program, ContinueWithLabelDemo
, uses nested loops to search for a substring within another string. Two nested loops are required: one to iterate over the substring and one to iterate over the string being searched. The following program, ContinueWithLabelDemo
, uses the labeled test
of continue
to skip an iteration in the outer loop.
class ContinueWithLabelDemo {
public static void main(String[] args) {
String searchMe = "Look for a substring in me";
String substring = "sub";
boolean foundIt = false;
int max = searchMe.length() -
substring.length();
test:
for (int i = 0; i <= max; i++) {
int n = substring.length();
int j = i;
int k = 0;
while (n-- != 0) {
if (searchMe.charAt(j++) != substring.charAt(k++)) {
continue test;
}
}
foundIt = true;
break test;
}
System.out.println(foundIt ? "Found it" : "Didn't find it");
}
}
Here is the output from this program.
Found it
The Return Statement
The next branching statements is the return
statement. The return
statement exits from the current method, and control flow returns to where the method was invoked. The return
statement has two forms: one that returns a value, and one that does not. To return a value, simply put the value (or an expression that calculates the value) after the return
keyword.
return ++count;
The data type of the returned value must match the type of the method's declared return
value. When a method is declared void
, use the form of return
that doesn't return a value.
return;
The Classes and Objects section will cover everything you need to know about writing methods.
The Yield Statement
The last branching statement is the yield
statement. The yield
statement exits from the current switch
expression it is in. A yield
statement is always followed by an expression that must produce a value. This expression must not be void
. The value of this expression is the value produced by the enclosing switch
expression.
Here is an example of a yield
statement.
class Test {
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public int calculate(Day d) {
return switch (d) {
case SATURDAY, SUNDAY -> 0;
default -> {
int remainingWorkDays = 5 - d.ordinal();
yield remainingWorkDays;
}
};
}
}
Last update: September 22, 2021