Introduction to Program Control Flow
Program execution isn't always a straightforward, top-to-bottom sequence. To create dynamic and interactive applications, developers need mechanisms to direct the order in which instructions are executed. These mechanisms are collectively known as program control structures. In Java, as in many other programming languages, there are three primary categories of control flow:
- Sequential Control: Instructions are executed one after another in the order they appear.
- Conditional (Branching) Control: Different blocks of code are executed based on whether specific conditions are met.
- Looping (Iterative) Control: A block of code is repeatedly executed until a certain condition is satisfied.
Sequential Execution
Sequential execution is the most basic form of control flow. Statements are processed in the exact order they are written, from the first line of code to the last, without any deviations or jumps. This is the default behavior of all programs.
For example, in Java, variables are defined and assigned values sequentially:
public class SequentialExample {
public static void main(String[] args) {
int initialValue = 10;
int calculatedValue = initialValue * 2;
System.out.println("Initial Value: " + initialValue); // First executed
System.out.println("Calculated Value: " + calculatedValue); // Second executed
}
}
Conditional Statements (Branching Control)
Conditional statements allow a program to make decisions, executing different code paths based on the evaluation of a boolean expression. Java provides several types of conditional constructs:
ifstatement (single condition)if-elsestatement (two possible outcomes)if-else if-elsestatement (multiple possible outcomes)switchstatement (for multiple fixed values)
The if Statement
The if statement executes a block of code only if a specified condition evaluates to true. If the condition is false, the code block is skipped.
Syntax
if (conditionExpression) {
// Code to execute if conditionExpression is true
}
Note: If the code block contains only a single statement, the curly braces {} are optional but recommended for clarity and to prevent errors when adding more statements later.
Example
Let's check if a user's input score indicates a passing grade (e.g., greater than 70).
import java.util.Scanner;
public class GradeChecker {
public static void main(String[] args) {
Scanner inputReader = new Scanner(System.in);
System.out.print("Enter your exam score: ");
int examScore = inputReader.nextInt();
if (examScore > 70) {
System.out.println("Congratulations! You passed.");
}
inputReader.close();
}
}
The if-else Statement
The if-else statement provides two possible execution paths. If the condition is true, the code block within the if is executed. Otherwise (if the condition is false), the code block within the else is executed.
Syntax
if (conditionExpression) {
// Code for true condition
} else {
// Code for false condition
}
Example
Determine if a given number is even or odd.
import java.util.Scanner;
public class ParityChecker {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter an integer: ");
int number = scanner.nextInt();
if (number % 2 == 0) {
System.out.println(number + " is an even number.");
} else {
System.out.println(number + " is an odd number.");
}
scanner.close();
}
}
The if-else if-else Statement
This structure is used when there are multiple conditions to test in sequence. The conditions are evaluated from top to bottom. The first condition that evaluates to true will have its corresponding code block executed, and the rest of the else if and else blocks will be skipped. If none of the if or else if conditions are met, the final else block (if present) is executed.
Syntax
if (condition1) {
// Code for condition1 true
} else if (condition2) {
// Code for condition2 true
} else if (conditionN) {
// Code for conditionN true
} else {
// Code if none of the above conditions are true
}
Note: An else block is optional. If omitted, and no conditions are met, no code within the entire if-else if structure will execute.
Example
Assigning letter grades based on a numerical score:
import java.util.Scanner;
public class StudentGrader {
public static void main(String[] args) {
Scanner inputScanner = new Scanner(System.in);
System.out.print("Enter student's numerical score (0-100): ");
int studentScore = inputScanner.nextInt();
if (studentScore >= 90 && studentScore <= 100) {
System.out.println("Grade: A (Excellent)");
} else if (studentScore >= 80 && studentScore < 90) {
System.out.println("Grade: B (Very Good)");
} else if (studentScore >= 70 && studentScore < 80) {
System.out.println("Grade: C (Good)");
} else if (studentScore >= 60 && studentScore < 70) {
System.out.println("Grade: D (Pass)");
} else if (studentScore >= 0 && studentScore < 60) {
System.out.println("Grade: F (Fail)");
} else {
System.out.println("Invalid score entered. Please enter a score between 0 and 100.");
}
inputScanner.close();
}
}
Nested Conditional Statements
Nested conditional statements occur when one if, if-else, or if-else if-else structure is placed inside another. The inner conditional statement is only evaluated if the outer condition (or a preceding outer condition) is met.
Example
Consider a scenario for a loyalty program. To qualify for a premium discount, a customer must be a member and have a purchase total above a certain threshold.
import java.util.Scanner;
public class DiscountCalculator {
public static void main(String[] args) {
Scanner reader = new Scanner(System.in);
System.out.print("Enter total purchase amount: $");
double purchaseAmount = reader.nextDouble();
System.out.print("Are you a loyalty member? (yes/no): ");
String isMemberInput = reader.next();
boolean isLoyaltyMember = isMemberInput.equalsIgnoreCase("yes");
if (purchaseAmount > 100.0) {
if (isLoyaltyMember) {
System.out.println("Eligible for Premium Discount (15% off)!");
} else {
System.out.println("Eligible for Standard Discount (10% off)!");
}
} else {
System.out.println("No discount applied for this purchase.");
}
reader.close();
}
}
The switch Statement
The switch statement is a multi-way branch statement. It provides an easier way to dispatch execution to different parts of code based on the value of a single expression. It's often more readable than a long if-else if-else chain when comparing an expression to a fixed set of values.
Syntax
switch (expression) {
case constant1:
// Code block for constant1
break;
case constant2:
// Code block for constant2
break;
// ... more cases
default:
// Code block if no match found
break;
}
Key points:
- The
expressionmust evaluate to a type that can be implicitly converted toint(byte,short,char), or it can be anint,Enum, orString(since Java 7). - Each
casevalue must be a compile-time constant literal. - The
breakstatement is crucial. Without it, execution "falls through" to the nextcaseblock (includingdefault), regardless of whether its constant matches, until abreakor the end of theswitchis encountered. - The
defaultblock is optional and is executed if none of thecasevalues match the expression.
Example
Displaying the name of a day based on a numerical input (1 for Monday, 2 for Tuesday, etc.).
import java.util.Scanner;
public class DayOfWeek {
public static void main(String[] args) {
Scanner dayScanner = new Scanner(System.in);
System.out.print("Enter a number (1-7) for the day of the week: ");
int dayNumber = dayScanner.nextInt();
String dayName;
switch (dayNumber) {
case 1:
dayName = "Monday";
break;
case 2:
dayName = "Tuesday";
break;
case 3:
dayName = "Wednesday";
break;
case 4:
dayName = "Thursday";
break;
case 5:
dayName = "Friday";
break;
case 6:
dayName = "Saturday";
break;
case 7:
dayName = "Sunday";
break;
default:
dayName = "Invalid Day Number";
break;
}
System.out.println("The day is: " + dayName);
dayScanner.close();
}
}
Looping Statements (Iterative Control)
Looping statements allow a block of code to be executed repeatedly as long as a specified condition remains true. Java provides three main types of loops:
forloop (ideal for a fixed number of iterations)whileloop (ideal when the number of iterations is not known beforehand)do-whileloop (guarantees at least one execution of the loop body)
The for Loop
The for loop is typically used when the number of iterations is known or can be determined before the loop starts. It consolidates initialization, condition checking, and iteration updating into a single line.
Syntax
for (initialization; terminationCondition; iterationStatement) {
// Code block to be executed repeatedly
}
Components:
- Initialization: Executed once when the loop starts (e.g.,
int i = 0;). - Termination Condition: Evaluated before each iteration. If
true, the loop body executes; iffalse, the loop terminates. - Iteration Statement: Executed after each iteration of the loop body (e.g.,
i++).
Example: Basic iteration
Printing a message a fixed number of times (e.g., 5 times):
public class ForLoopDemo {
public static void main(String[] args) {
for (int count = 1; count <= 5; count++) {
System.out.println("Loop iteration: " + count);
}
}
}
Example: Calculating sum and count of multiples
Find all numbers between 1 and 150 that are multiples of 7, then count them and calculate their sum.
public class MultiplesOfSeven {
public static void main(String[] args) {
int multipleCount = 0;
int totalSum = 0;
for (int currentNum = 1; currentNum <= 150; currentNum++) {
if (currentNum % 7 == 0) {
totalSum += currentNum;
multipleCount++;
}
}
System.out.println("Count of multiples of 7 (1-150): " + multipleCount);
System.out.println("Sum of multiples of 7 (1-150): " + totalSum);
}
}
Example: Generating a mathematical pattern
Print pairs of numbers that sum to 10, for example, 0 + 10 = 10, 1 + 9 = 10, etc.
public class SumPattern {
public static void main(String[] args) {
int fixedSum = 10;
for (int numX = 0; numX <= fixedSum; numX++) {
int numY = fixedSum - numX;
System.out.println(numX + " + " + numY + " = " + (numX + numY));
}
}
}
The while Loop
The while loop repeatedly executes a block of code as long as its condition remains true. The condition is checked *before* each iteration. If the condition is initially false, the loop body will never execute.
Syntax
while (conditionExpression) {
// Code block to be executed
// Increment/decrement or other update to eventually make conditionExpression false
}
Important: Ensure that the loop body contains logic that will eventually cause the conditionExpression to become false, otherwise, it will result in an infinite loop.
Example: Simple counter
Print a message 5 times using a while loop.
public class WhileLoopDemo {
public static void main(String[] args) {
int counter = 1;
while (counter <= 5) {
System.out.println("While loop iteration: " + counter);
counter++; // Essential to avoid infinite loop
}
}
}
Example: Finding numbers divisible by 5
Print all numbers between 1 and 100 that are divisible by 5.
public class DivisibleByFive {
public static void main(String[] args) {
int currentNumber = 1;
while (currentNumber <= 100) {
if (currentNumber % 5 == 0) {
System.out.println(currentNumber + " is divisible by 5.");
}
currentNumber++;
}
}
}
The do-while Loop
The do-while loop is similar to the while loop, but with one crucial difference: its condition is checked *after* the loop body has executed at least once. This guarantees that the code block within the loop will always run atleast one time, even if the condition is initially false.
Syntax
do {
// Code block to be executed
// Increment/decrement or other update
} while (conditionExpression); // Note the semicolon!
Example
A simple scenario demonstrating the "at least once" execution guarantee:
public class DoWhileDemo {
public static void main(String[] args) {
int initialVal = 0;
do {
System.out.println("This message prints at least once. Current value: " + initialVal);
initialVal++;
} while (initialVal < 0); // Condition is false, but code runs once
System.out.println("Loop finished. Final value: " + initialVal);
}
}
Nested Loops
Nested loops involve placing one loop inside another. The inner loop completes all its iterations for each single iteration of the outer loop. This structure is commonly used for tasks like processing two-dimensional data structures or generating patterns.
Example: Generating a Multiplication Table
The classic 9x9 multiplication table is a perfect example of nested loops:
public class MultiplicationTable {
public static void main(String[] args) {
for (int i = 1; i <= 9; i++) { // Outer loop for multiplicand
for (int j = 1; j <= i; j++) { // Inner loop for multiplier, up to current multiplicand
System.out.print(j + " * " + i + " = " + (i * j) + "\t"); // Use tab for spacing
}
System.out.println(); // Move to the next line after each row
}
}
}
Jump Control Statements
Jumpp statements alter the flow of execution within loops and switch statements. Java provides break and continue.
The break Statement
The break statement is used to terminate the enclosing switch statement or loop (for, while, or do-while) immediately. Execution then resumes at the statement immediately following the terminated construct.
Example
public class BreakExample {
public static void main(String[] args) {
for (int k = 0; k < 10; k++) {
if (k == 5) {
System.out.println("Value k reached 5. Breaking loop.");
break; // Exit the for loop
}
System.out.println("Current value of k: " + k);
}
System.out.println("Loop terminated.");
}
}
The continue Statement
The continue statement skips the rest of the current iteration of the innermost loop (for, while, or do-while) and proceeds to the next iteration. It does not terminate the loop entirely.
Example
public class ContinueExample {
public static void main(String[] args) {
for (int m = 0; m < 5; m++) {
if (m == 2) {
System.out.println("Skipping iteration for m = 2.");
continue; // Skip the rest of this iteration, go to next
}
System.out.println("Processing iteration for m = " + m);
}
System.out.println("Loop finished.");
}
}
Practice Exercises
Exercise 1: Road Toll Calculator
A person has an initial amount of $100,000. They encounter a toll booth repeatedly. The toll rules are:
- If current cash > $50,000, they pay 5% of their current cash.
- If current cash ≤ $50,000, they pay $1,000.
How many toll booths can the person pass before their cash drops below $1,000 (meaning they can no longer pay the $1,000 toll)?
public class TollBoothSimulation {
public static void main(String[] args) {
double currentCash = 100000.0;
int boothsPassed = 0;
while (true) { // Loop indefinitely until an explicit break
if (currentCash > 50000.0) {
currentCash -= (currentCash * 0.05); // Deduct 5%
} else if (currentCash >= 1000.0) { // Check if enough for $1000 toll
currentCash -= 1000.0; // Deduct fixed amount
} else {
// If currentCash is less than 1000 and cannot pay the toll
break;
}
boothsPassed++;
}
System.out.println("The person can pass " + boothsPassed + " toll booths.");
}
}
Exercise 2: Narcissistic Number Checker
Determine if an input integer is a "Narcissistic Number" (also known as an Armstrong number). For a three-digit number, this means the sum of the cubes of its digits equals the number itself. For example, 153 = 1³ + 5³ + 3³.
import java.util.Scanner;
public class NarcissisticNumber {
public static void main(String[] args) {
Scanner numScanner = new Scanner(System.in);
System.out.print("Enter a three-digit integer to check for Narcissistic property: ");
int inputNumber = numScanner.nextInt();
if (inputNumber < 100 || inputNumber > 999) {
System.out.println("Please enter a valid three-digit number.");
} else {
int digitHundreds = inputNumber / 100; // e.g., 153 / 100 = 1
int digitTens = (inputNumber % 100) / 10; // e.g., (153 % 100) / 10 = 53 / 10 = 5
int digitUnits = inputNumber % 10; // e.g., 153 % 10 = 3
int sumOfCubes = (int)(Math.pow(digitHundreds, 3) +
Math.pow(digitTens, 3) +
Math.pow(digitUnits, 3));
if (sumOfCubes == inputNumber) {
System.out.println(inputNumber + " is a Narcissistic Number.");
} else {
System.out.println(inputNumber + " is NOT a Narcissistic Number.");
}
}
numScanner.close();
}
}
Exercise 3: Leap Year Detector
Write a program to determine if an inputted year is a leap year. A leap year satisfies one of the following conditions:
- It is divisible by 4 but not by 100.
- It is divisible by 400.
import java.util.Scanner;
public class LeapYearDetector {
public static void main(String[] args) {
Scanner yearScanner = new Scanner(System.in);
System.out.print("Enter a year to check: ");
int testYear = yearScanner.nextInt();
// A year is a leap year if it's divisible by 400
// OR (divisible by 4 AND NOT divisible by 100)
if ((testYear % 4 == 0 && testYear % 100 != 0) || (testYear % 400 == 0)) {
System.out.println(testYear + " is a leap year.");
} else {
System.out.println(testYear + " is NOT a leap year.");
}
yearScanner.close();
}
}