Java Programming/Flow control
| Navigate Language Fundamentals topic: |
Control flow, common to all popular programming languages, is the method used to control the order in which code executes. Because solutions are rarely simple enough to just start at the top and finish at the bottom, there are always going to be times when you either want something to be done which relies on something else (conditional) or to repeat certain tasks (loops).
Contents |
[edit] Boolean logic
Before you can understand how conditional control works, you must understand how boolean logic works. Boolean values are values that evaluate to either true or false, and are represented by the boolean data type. Boolean expressions are very similar to mathematical expressions, but instead of using mathematical operators such as "+" or "-", you use comparative or boolean operators such as "==" or "!".
[edit] Comparative operators
Java has several operators that can be used to compare variables. For example, how would you tell if one variable has a greater value than another? The answer: use the "greater-than" operator.
Here is a list of the comparative operators in Java:
>: Greater than<: Less than>=: Greater than or equal to<=: Less than or equal to==: Equal to!=: Not equal to
To see how these operators are used, look at this example:
int a = 5, b = 3; boolean value; value = a > b; // Value is true because a is greater than b value = a == b; // Value is false because a does not equal b value = b <= a; // Value is true because b is less than a System.out.println(value); // Prints out "true" because the last statement evaluated to true |
Comparative operators can be used on any primitive types (except boolean), but only the "equals" and "does not equal" operators work on objects. This is because the less-than/greater-than operators cannot be applied to objects, but the equivalency operators can.
Specifically, the == and != operators test whether both variables point to the same object. Objects will be covered later in the tutorial, in the "Classes, Objects, and Types" module. |
[edit] Boolean operators
Boolean operators operate directly on boolean values.
Here is a list of three common boolean operators in Java:
!: Boolean NOT&&: Boolean AND||: Boolean inclusive OR
The boolean NOT operator ("!") inverts the value of a boolean expression. The boolean AND operator ("&&") will result in true if and only if the values on both sides of the operator are true. The boolean inclusive OR operator ("||") will result in true if either or both of the values on the sides of the operator is true.
To show how these operators are used, here is an example:
boolean a = true, b = false, value; value = !a; // Value is false because a is true value = a || b; // Value is true because a is true, even though b is false value = a && b; // Value is false because b is false, even though a is true value = a && 5 > 3; // Value is true because a is true and "5 > 3" evaluates to true System.out.println(value); // Prints out "true" because the last statement evaluated to true |
The && and || operators should not be confused with & and |. & and | are both bitwise operators, which are out of the scope of this module. |
Here are the truth tables for the boolean operators:
!a
| a | Result |
|---|---|
| true | false |
| false | true |
a || b
| a | b | result |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
a && b
| a | b | result |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
In Java, boolean logic has a useful property called "short circuiting". This means that expressions will only be evaluated as far as necessary. In the expression (a && b), if a is false, then b will not be evaluated because the expression will be false no matter what. For help on simplifying complex logic, see De Morgan's laws. |
[edit] Conditional statements
Conditional statements allow a program to take a different path depending on some condition.
[edit] If
The if statement is a section of code that only executes if the associated boolean expression is true. The if statement may optionally be followed by an else statement which will execute if that boolean expression is false.
The structure of an if statement is as follows:
if (<boolean expression>) { // Do something } else { // Do something else } |
Additionally, if code is to be executed based on more conditions, an else-if statement may be used. else-if statements come after the if statement, but before the else statement.
The structure of an if-else-if statement is as follows:
if (<boolean expression>) { // Do something } else if (<another boolean expression>) { // Do another thing } else { // Do something else } |
Here is an example to illustrate:
int a = -5; if (a > 0) { System.out.println("a is positive"); // a is not greater than 0, so this statement will not execute } else if (a < 0) { System.out.println("a is negative"); // a IS less than 0, so this statement will execute } else { System.out.println("a is zero"); // a does not equal 0, so this statement will not execute } |
[edit] Switch
The switch statement evaluates an integer (or enum, starting in J2SE 5.0; or String, starting in J2SE 7.0), and, based on the value provided, jumps to a specific case within the switch block and executes code until the break command is encountered or the end of the block. If the switch value does not match any of the case values, execution will jump to the optional default case.
The structure of a switch statement is as follows:
switch (<integer or enum or String value>) { case <case value>: // Do something break; case <another case value>: // Do something else break; default: // Optional default handling } |
Here is an example to illustrate:
int i = 3; switch(i) { case 1: System.out.println("i equals 1"); // i doesn't equal 1, so this code won't execute break; case 2: System.out.println("i equals 2"); // i doesn't equal 2, so this code won't execute break; default: System.out.println("i equals something other than 1 or 2"); // i has not been handled so far, so this code will execute } |
If the break statement does not end a case, then it will fall through to the case below.
Look at this example to see how it's done:
int i = -1; switch(i) { case -1: case 1: System.out.println("i is 1 or -1"); // i is -1, so it will fall through to this case and execute this code break; case 0: System.out.println("i is 0"); // The break command is used before this case, so if i is 1 or -1, this will not execute } |
Starting in J2SE 5.0, the switch statement can also be used with an enum value instead of an integer.
Though enums have not been covered yet, here is an example so you can see how it's done (note that the enum constants in the cases do not need to be qualified with the type:
Day day = Day.MONDAY; // Day is a fictional enum type containing the days of the week switch(day) { case MONDAY: System.out.println("Mondays are the worst!"); // Since day == Day.MONDAY, this statement will execute break; case TUESDAY: case WEDNESDAY: case THURSDAY: System.out.println("Weekdays are so-so."); break; case FRIDAY: case SATURDAY: case SUNDAY: System.out.println("Weekends are the best!"); break; } |
Starting in J2SE 7.0, the switch statement can also be used with an String value instead of an integer.
String day = "Monday"; switch(day) { case "Monday": System.out.println("Mondays are the worst!"); // Since day == Day.MONDAY, this statement will execute break; case "Tuesday": case "Wednesday": case "Thursday": System.out.println("Weekdays are so-so."); break; case "Friday": case "Saturday": case "Sunday": System.out.println("Weekends are the best!"); break; default: throw new IllegalArgumentException("Invalid day of the week: " + day); } |
[edit] Conditional loops
Computers are very good at repeating tasks. Conditional loops allow you to repeatedly perform a task until a certain state is reached. Conditional loops are called such because they loop until a condition is met.
Say we want to print the numbers from one to 10. Without the use of loops, we would have to start writing out the code line-by-line, but with loops, the code can look like the following (do not worry about understanding it, we will get to that in a bit):
for (int i = 1; i <= 10; i++) System.out.println("i = " + i); |
Using loops, we've taken 10 lines of code and turned them into just 2, but the most important part of loops is that they can be performed an arbitrary number of times.
[edit] While
While loops are the simplest form of loop. The while loop comes in two forms.
The normal while loop repeats a block of code while the specified condition is true. Here is the structure of a while loop:
while (<condition>) { // Some code } |
The loop's condition is checked before each iteration of the loop. If the condition is false at the start of the loop, the loop will not be executed at all.
If you want to perform a task a specific number of times, you should use the following algorithm:
int i = 0; while (i < <number of iterations>) { // Some code i++; } |
Though you haven't learned about arrays yet, you can iterate through a list or array using this algorithm by replacing <number of iterations> with array.length. Then, you can use array[i] to access the array index at the current iteration.
If a loop's condition will never become false, such as if the true constant is used for the condition, said loop is known as an infinite loop. Such a loop will repeat indefinitely unless it is broken out of. Infinite loops can be used to perform tasks that need to be repeated over and over again without a definite stopping point, such as updating a graphics display. |
[edit] Do... while
The do-while statement is like the while, but it will execute a block of code at least once and continue execution as long as the condition is true.
do { // Some code } while (<condition>); |
[edit] For
The for loop provides additional flow control over a while statement. Do you remember the algorithm for looping a certain number of times that was shown earlier? The for loop is like a template version of that.
The for loop consists of the keyword for followed by three extra statements enclosed in parentheses. The first statement is the variable declaration statement, which allows you to declare one or more integer variables. The second is the condition, which is checked the same way as the while loop. Last is the iteration statement, which is used to increment or decrement variables, though any statement is allowed.
This is the structure of a for loop:
for (<variable declarations>; <condition>; <iteration statement>) { // Code } |
To clarify how a for loop is used, here is an example:
for (int i = 1, j = 10; i <= 10; i++, j--) { System.out.print(i + " "); System.out.println(j); } |
This example shows how to iterate with the for statement using multiple variables. It will print the following:
1 10 2 9 3 8 4 7 5 6 6 5 7 4 8 3 9 2 10 1 |
Any of the parameters of a for loop can be skipped. Skip them all, and you have an infinitely repeating loop, as such:
for (;;) { // Some code } |
[edit] For-each
Arrays haven't been covered yet, but you'll want to know how to use the enhanced for loop, called the for-each loop. The for-each loop automatically iterates through a list or array and assigns the value of each index to a variable.
To understand the structure of a for-each loop, look at the following example:
String[] sentence = {"I", "am", "a", "Java", "program."}; for (String word : sentence) { System.out.print(word + " "); } |
The example iterates through an array of words and prints them out like a sentence. What the loop does is iterate through sentence and assign the value of each index to word, then execute the code block.
Here is the general contract of the for-each loop:
for (<variable declaration> : <array or list>) { // Some code } |
Make sure that the type of the array or list is assignable to the declared variable, or you will get a compilation error.
[edit] Break and continue keywords
The break keyword exits a flow control loop, such as a for loop. It basically breaks the loop.
For example, look at the following code:
for (int i = 1; i <= 10; i++) { System.out.println(i); if (i == 5) { System.out.println("STOP!"); break; } } |
Normally, the loop would print out all the numbers from 1 to 10, but we have a check for when i equals 5. When the loop reaches its fifth iteration, it will be cut short by the break statement, at which point it will exit the loop.
This piece of code will print out:
1 2 3 4 5 STOP! |
The continue keyword jumps to the next iteration of a loop (before the condition is checked).
Here is an example of the continue statement in action:
for (int i = 1; i <= 10; i++) { if (i == 5) { System.out.println("Caught i == 5"); continue; } System.out.println(i); } |
This will print out:
1 2 3 4 Caught i == 5 6 7 8 9 10 |
[edit] Labels
Labels can be used to give a name to a loop. The reason to do this is so we can break out of or continue with upper-level loops from a nested loop.
Here is how to label a loop:
<label name>: <loop> |
To break out of or continue with a loop, use the break or continue keyword followed by the name of the loop.
For example:
int i, j; int[][] nums = { {1, 2, 5}, {6, 9, 7}, {8, 3, 4} }; Outer: for (i = 0; i < nums.length; i++) { for (j = 0; j < nums[i].length; j++) { if (nums[i][j] == 9) { System.out.println("Found number 9 at (" + i + ", " + j + ")"); break Outer; } } } |
This will print (1, 1).
You needn't worry if you don't understand all the code, but look at how the label is used to break out of the outer loop from the inner loop.
[edit] Try... catch statements
The try-catch statements are used to catch any exceptions or other throwable objects within the code.
Here's what a try-catch statement looks like:
try { // Some code } catch (Exception e) { // Handle exception here } |
In addition to the try and catch blocks, a finally block may be present. The finally block is always executed, even if an exception is thrown. It may appear with or without a catch block, but always with a try block.
Here is what a finally block looks like:
try { // Some code } catch (Exception e) { // Optional exception handling } finally { // This code is executed no matter what } |
Exception handling isn't going to be covered any time soon, but you should be aware of these constructs.
[edit] Examples
-
public class GetBinary {
-
public static void main(String[] args) {
-
if (args.length == 0) {
-
// Print usage
-
System.out.println("Usage: java GetBinary <decimal integer>");
-
System.exit(0);
-
} else {
-
// Print arguments
-
System.out.println("Received " + args.length + " arguments.");
-
System.out.println("The arguments are:");
-
for (String arg : args) {
-
System.out.println("\t" + arg);
-
}
-
}
-
-
int number = 0;
-
String binary = "";
-
-
// Get the input number
-
try {
-
number = Integer.parseInt(args[0]);
-
} catch (NumberFormatException ex) {
-
System.out.println("Error: argument must be a base-10 integer.");
-
System.exit(0);
-
}
-
-
// Convert to a binary string
-
do {
-
switch (number % 2) {
-
case 0: binary += '0'; break;
-
case 1: binary += '1'; break;
-
}
-
number >>= 1;
-
} while (number > 0);
-
-
System.out.println("The binary representation of " + args[0] + " is " + binary);
-
}
-
}
public class GetBinary { public static void main(String[] args) { if (args.length == 0) { // Print usage System.out.println("Usage: java GetBinary <decimal integer>"); System.exit(0); } else { // Print arguments System.out.println("Received " + args.length + " arguments."); System.out.println("The arguments are:"); for (String arg : args) { System.out.println("\t" + arg); } } int number = 0; String binary = ""; // Get the input number try { number = Integer.parseInt(args[0]); } catch (NumberFormatException ex) { System.out.println("Error: argument must be a base-10 integer."); System.exit(0); } // Convert to a binary string do { switch (number % 2) { case 0: binary += '0'; break; case 1: binary += '1'; break; } number >>= 1; } while (number > 0); System.out.println("The binary representation of " + args[0] + " is " + binary); } }
This is a simulation of playing a game called Lucky Sevens. It is a dice game where the player rolls two dice. If the numbers on the dice add up to seven, he wins $4. If they do not, he loses $1. The game shows how to use control flow in a program as well as the fruitlessness of gambling.
-
import java.util.*;
-
-
public class LuckySevens {
-
public static void main(String[] args) {
-
Scanner in = new Scanner(System.in);
-
Random random = new Random();
-
String input;
-
int startingCash, cash, maxCash, rolls, roll;
-
-
// Loop until "quit" is input
-
while (true) {
-
System.out.print("Enter the amount of cash to start with (or \"quit\" to quit): ");
-
-
input = in.nextLine();
-
-
// Check if user wants to exit
-
if (input.toLowerCase().equals("quit")) {
-
System.out.println("\tGoodbye.");
-
System.exit(0);
-
}
-
-
// Get number
-
try {
-
startingCash = Integer.parseInt(input);
-
} catch (NumberFormatException ex) {
-
System.out.println("\tPlease enter a positive integer greater than 0.");
-
continue;
-
}
-
-
// You have to start with some money!
-
if (startingCash <= 0) {
-
System.out.println("\tPlease enter a positive integer greater than 0.");
-
continue;
-
}
-
-
cash = startingCash;
-
maxCash = cash;
-
rolls = 0;
-
roll = 0;
-
-
// Here is the game loop
-
for (; cash > 0; rolls++) {
-
roll = random.nextInt(6) + 1;
-
roll += random.nextInt(6) + 1;
-
-
if (roll == 7)
-
cash += 4;
-
else
-
cash -= 1;
-
-
if (cash > maxCash)
-
maxCash = cash;
-
}
-
-
System.out.println("\tYou start with $" + startingCash + ".\n"
-
+ "\tYou peak at $" + maxCash + ".\n"
-
+ "\tAfter " + rolls + " rolls, you run out of cash.");
-
}
-
}
-
}
import java.util.*; public class LuckySevens { public static void main(String[] args) { Scanner in = new Scanner(System.in); Random random = new Random(); String input; int startingCash, cash, maxCash, rolls, roll; // Loop until "quit" is input while (true) { System.out.print("Enter the amount of cash to start with (or \"quit\" to quit): "); input = in.nextLine(); // Check if user wants to exit if (input.toLowerCase().equals("quit")) { System.out.println("\tGoodbye."); System.exit(0); } // Get number try { startingCash = Integer.parseInt(input); } catch (NumberFormatException ex) { System.out.println("\tPlease enter a positive integer greater than 0."); continue; } // You have to start with some money! if (startingCash <= 0) { System.out.println("\tPlease enter a positive integer greater than 0."); continue; } cash = startingCash; maxCash = cash; rolls = 0; roll = 0; // Here is the game loop for (; cash > 0; rolls++) { roll = random.nextInt(6) + 1; roll += random.nextInt(6) + 1; if (roll == 7) cash += 4; else cash -= 1; if (cash > maxCash) maxCash = cash; } System.out.println("\tYou start with $" + startingCash + ".\n" + "\tYou peak at $" + maxCash + ".\n" + "\tAfter " + rolls + " rolls, you run out of cash."); } } }