Conditional Statements
So far, our programs have followed a straightforward execution from top to bottom, without incorporating any conditions or conditional behavior. However, in most cases, we need to include conditional logic in our programs. This logic is dependent on the state of the program's variables.
To introduce conditional branching in a program based on user input, we need to use what is known as a conditional statement. The most basic form of a conditional statement is as follows.
System.out.println("Hello, world!");
if (true) {
System.out.println("This code is unavoidable!");
}
Hello, world! This code is unavoidable!
Conditional statements are used to make decisions based on the state of the program's variables. In Java, the most basic conditional statement is the if
statement. It begins with the keyword if
, followed by parentheses that contain an expression to be evaluated.
The expression inside the parentheses is evaluated when the conditional statement is reached. The result of the evaluation is a boolean value. If the expression evaluates to true
, the source code inside the block that follows the conditional statement is executed. On the other hand, if the expression evaluates to false
, the execution skips the source code inside the block and moves on to the statement after the closing curly bracket of the current conditional statement.
It's important to note that an if
statement is not followed by a semicolon because the statement doesn't end after the conditional. Instead, the curly braces {}
are used to define the block of code to be executed when the condition is true
.
Here's an example that compares two numbers in a conditional statement:
int number = 11;
if (number < 10) {
System.out.println("The number was less than 10");
}
In this example, the variable number
is assigned a value of 11
. The condition inside the parentheses, number < 10
, evaluates to false
. Therefore, the source code inside the block that follows the conditional statement is not executed and the sentence "The number was less than 10" will not be printed.
Code Indentation and Block Statements
A code block is a section of code enclosed by a pair of curly brackets. In Java, the source file containing a program must include the string public class
, followed by the name of the program and the opening curly bracket of the block. The block ends with a closing curly bracket. The recurring snippet public static void main(String[] args)
begins a block, and the source code within it is executed when the program is run. This snippet is the starting point of all Java programs. Blocks define a program's structure and its boundaries. It's important to note that a curly bracket must always have a matching pair: any code missing a closing (or opening) curly bracket is invalid.
A conditional statement also marks the start of a new code block. In addition to defining program structure and functionality, block statements have an effect on the readability of a program. Code inside a block is typically indented for clarity. For example, any source code inside the block of a conditional statement is indented four spaces deeper than the if
command that started the conditional statement. Four spaces can also be added by pressing the tab
key. When the block ends with a }
character, the indentation also ends. The }
character should be at the same level of indentation as the if
command that started the conditional statement.
The example below shows correct indentation:
if (number > 10) {
number = 9;
}
In Java, code should be indented consistently with either four spaces or a single tab for each block. It's important to use only one of these methods for indentation, not both. To automatically indent code in IntelliJ, use the shortcut Ctrl + alt + L
. From now on, it's important to indent code correctly in exercises and graded assignments, as incorrect indentation may result in lost style points.
Relational Operators
As you may have noticed, conditional statements often use comparison operators, also known as relational operators
, to compare numbers. Java provides a set of standard relational operators for this purpose:
>
greater than>=
greater than or equal to<
less than<=
less than or equal to==
equal to!=
not equal to
An example of two relational operators being used in code is given below:
int number = 55;
if (number != 0) {
System.out.println("The number is not equal to 0");
}
if (number >= 1000) {
System.out.println("The number is at least 1000");
}
Else
If the expression inside the parentheses of the conditional statement evaluates to false, then the execution of the code moves to the statement following the closing curly bracket of the current conditional statement. This is not always desirable, and usually, we want to provide an alternative option when the conditional expression evaluates to false. This can be achieved using the else
command, which is used together with the if
command.
int number = 4;
if (number > 5) {
System.out.println("Your number is greater than five!");
} else {
System.out.println("Your number is five or less!");
}
If an else
branch has been specified for a conditional statement, the block defined by the else
branch is executed when the condition of the conditional statement is false. The else
command is placed on the same line as the closing bracket of the block defined by the if
command. In the example stated above, the argument for the if-statement is false, so the program will execute the block under the else
command. The output will be: "Your number is five or less."
More Conditionals: else if
In cases where there are multiple conditions to be evaluated, we use the else if
command. This command is placed after the initial if
condition and can be used multiple times.
int number = 3;
if (number == 1) {
System.out.println("The number is one");
} else if (number == 2) {
System.out.println("The given number is two");
} else if (number == 3) {
System.out.println("The number must be three!");
} else {
System.out.println("Something else!");
}
Let's read out the example above: 'If the number is one, then print "The number is one", else if the number is two, then print "The given number is two", else if the number is three, then print "The number must be three!". Otherwise, print "Something else!"'
The step-by-step visualization of the code above is as follows:
In the following video, we show what it looks like when we write a program using if, else and if-else systems in IntelliJ.
Conditional Statement Expression and the Boolean Variable
The expression inside the parentheses of a conditional statement must evaluate to a boolean value, which can either be true
or false
. A conditional statement can also be constructed with a boolean variable, like so:
boolean isItTrue = true;
if (isItTrue) {
System.out.println("Pretty wild!");
}
Apart from being used in conditionals, comparison operators can also be used to produce boolean values that can be stored in boolean variables for later use. For example:
int first = 1;
int second = 3;
boolean isGreater = first > second;
In the example above, the boolean variable isGreater
now stores the boolean value false
. We can further extend the previous example by adding a conditional statement:
int first = 1;
int second = 3;
boolean isLessThan = first < second;
if (isLessThan) {
System.out.println("1 is less than 3!");
}
The program will output: 1 is less than 3!
Modulo operator
An operator which is very useful when we want to check the divisibility of a number is the modulo operator. The symbol for this modulo operator is %
and the output of a modulo operator is the remainder after division of the first number by the second number.
int remainder = 7 % 2;
System.out.println(remainder); // prints 1
System.out.println(5 % 3); // prints 2
System.out.println(7 % 4); // prints 3
System.out.println(8 % 4); // prints 0
System.out.println(1 % 2); // prints 1
For instance, if we would want to know whether a number given by the user is divisible by four hundred, we could check if the remainder is zero after taking the modulo of the number and four hundred. Since the modulo is an operation just like other calculations, it can be a part of an expression in a conditional statement.
Scanner reader = new Scanner(System.in);
int number = Integer.valueOf(reader.nextLine());
if (number % 400 == 0) {
System.out.println("The number " + number + " is divisible by four hundred.");
} else {
System.out.println("The number " + number + " is not divisible by four hundred.");
}
Conditional Statements and Comparing Strings
Although integers, floating-point numbers, and boolean values can be compared using two equals signs (variable1 == variable2
), the same approach cannot be used for comparing the equality of strings.
You can try this with the following program:
Scanner reader = new Scanner(System.in);
System.out.println("Enter the first string");
String first = reader.nextLine();
System.out.println("Enter the second string");
String second = reader.nextLine();
if (first == second) {
System.out.println("The strings were the same!");
} else {
System.out.println("The strings were different!");
}
Enter the first string same Enter the second string same The strings were different!
Enter the first string same Enter the second string different The strings were different!
This is due to how Java implements variable comparison and the internal workings of strings. Since strings can contain a limitless number of characters, and variables that contain only one number or value can be compared using an equals sign, using such method for strings doesn't work. We will explore this topic further in this course.
When comparing strings, it is important to use the equals
command, which is specifically designed for string variables. This command is written after a string by appending it to the end of the string to be compared using a dot. It takes a parameter, which is the string to be compared against the variable. If the variable is being compared with a string directly, the string can be placed inside the parentheses of the equals
command, enclosed in quotation marks. On the other hand, if a string variable holds the string to be compared, the name of the variable should be placed inside the parentheses. The equals
command works as follows:
Scanner reader = new Scanner(System.in);
System.out.println("Enter a string");
String input = reader.nextLine();
if (input.equals("a string")) {
System.out.println("Great! You read the instructions correctly.");
} else {
System.out.println("Missed the mark!");
}
In the example below the user is prompted for two strings. We first check to see if the provided strings are the same, after which we check if the value of either one of the two strings is "two strings".
Scanner reader = new Scanner(System.in);
System.out.println("Input two strings");
String first = reader.nextLine();
String second = reader.nextLine();
if (first.equals(second)) {
System.out.println("The strings were the same!");
} else {
System.out.println("The strings were different!");
}
if (first.equals("two strings")) {
System.out.println("Clever!");
}
if (second.equals("two strings")) {
System.out.println("Sneaky!");
}
Logical Operators
A conditional statement can contain an expression consisting of multiple parts, which can be combined using logical operators such as the and operator &&
, or operator ||
, and not operator !
.
- An expression that is made up of two expressions combined using the and-operator is only true if both of the expressions being combined evaluate to true.
- An expression that is made up of two expressions combined using the or-operator is true if either one, or both, of the expressions being combined evaluate to true.
- It is important to note that logical operators do not change the boolean value from true to false or false to true. They only combine and evaluate expressions.
In the next example we combine two individual conditions using the and-operator (&&
). The code is used to check if number
is greater than or equal to 5 and less than or equal to 10. In other words, we check whether 7 is within the range of 5-10, which should give the output "It is!":
System.out.println("Is the number within the range 5-10? ");
int number = 7;
if (number >= 5 && number <= 10) {
System.out.println("It is! :)");
} else {
System.out.println("It is not :(")
}
In the next example we provide two conditions using the or-operator (||
): is the number less than zero or greater than 100? The condition is fulfilled if the number fulfills either one of the two conditions, which is true for the number 145 for instance:
System.out.println("Is the number less than 0 or greater than 100");
int number = 145;
if (number < 0 || number > 100) {
System.out.println("It is! :)");
} else {
System.out.println("It is not :(");
}
In the next example we flip the result of the expression number > 4
using the not-operator (!
). The not-operator is written in such a way that the expression to be flipped is wrapped in parentheses, whilst the not-operator is placed before these parentheses.
int number = 7;
if (!(number > 4)) {
System.out.println("The number is not greater than 4.");
} else {
System.out.println("The number is greater than 4.");
}
Execution order
Order of Execution for Comparisons
Comparisons are always executed top down. Whenever execution reaches a conditional statement whose condition is true
, its block is executed and the comparison stops.
int number = 5;
if (number == 0) {
System.out.println("The number is zero.");
} else if (number > 0) {
System.out.println("The number is greater than zero.");
} else if (number > 2) {
System.out.println("The number is greater than two.");
} else {
System.out.println("The number is less than zero.");
}
The example above prints the string "The number is greater than zero." even if the condition number > 2
is true. The comparison namely stops at the first condition that evaluates
to true.
Execution Order of Conditional Statements
Let's familiarize ourselves with the execution order of conditional statements through a classic programming exercise.
'Write a program that prompts the user for a number between one and one hundred, and prints that number. If the number is divisible by three, then print "Fizz" instead of the number. If the number is divisible by five, then print "Buzz" instead of the number. If the number is divisible by both three and five, then print "FizzBuzz" instead of the number.'
The programmer begins to solve the exercise by reading the exercise description and by writing code according to the description. The conditions for execution are presented in a given order by the description, and the initial structure for the program is formed based on that order. The structure is formed based on the following steps:
- Write a program that prompts the user for a number and prints that number.
- If the number is divisible by three, then print "Fizz" instead of the number.
- If the number is divisible by five, then print "Buzz" instead of the number.
- If the number is divisible by both three and five, then print "FizzBuzz" instead of the number.
If-type conditions are easy to implement using if
- else if
- else
-conditional statements. The code below was written based on the steps above, but it does not work correctly, which we can see from the example.
Scanner reader = new Scanner(System.in);
int number = 15;
if (number % 3 == 0) {
System.out.println("Fizz");
} else if (number % 5 == 0) {
System.out.println("Buzz");
} else if (number % 3 == 0 && number % 5 == 0) {
System.out.println("FizzBuzz");
} else {
System.out.println(number);
}
The problem with the previous approach is that the parsing of conditional statements stops at the first condition that is true. E.g., with the value 15 the string "Fizz" is printed, since the number is divisible by three (15 % 3 == 0), whereas we would actually want to see "FizzBuzz".
One approach for improving and developing the correct train of thought would be to first find the most demanding condition, and implement it. After that, we would implement the other conditions. In the example above, the condition "if the number is divisible by both three and five" requires two things to happen. Now the train of thought would be:
- Write a program that reads input from the user.
- If the number is divisible by both three and five, then print "FizzBuzz" instead of the number.
- If the number is divisible by three, then print "Fizz" instead of the number.
- If the number is divisible by five, then print "Buzz" instead of the number.
- Otherwise, the program prints the number given by the user.
This corresponds to the following code:
Scanner reader = new Scanner(System.in);
int number = Integer.valueOf(reader.nextLine());
if (number % 3 == 0 && number % 5 == 0) {
System.out.println("FizzBuzz");
} else if (number % 3 == 0) {
System.out.println("Fizz");
} else if (number % 5 == 0) {
System.out.println("Buzz");
} else {
System.out.println(number);
}