4. Logical Operators¶
4.1. Objectives¶
- Identify and use the 3 logical operators in Java
4.2. Time Goal¶
- 20 minutes on this section
4.3. Key Terms¶
- logical operator
- An operator that combines boolean values and produces a boolean value.
- logical and
- Used to only execute the following statement or block of statements if both conditions are true
- logical or
- Used to execute the following statement or block of statements if one of the conditions are true
- complex conditional
- A Boolean expression containing at least one logical operator, used to determine whether or not a block of statements should execute
- short circuit
- The type of evaluation used for logical and
&&
and logical or||
expressions. If the first condition is false in a complex conditional with a logical and the second condition won’t be evaluated. If the first condition is true in a complex conditional with a logical or the second condition won’t be evaluated.- negation
- turns a true statement false and a false statement true
4.4. Exercises¶
Note
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.
Examples:
x > 0 && x < 10
istrue
when x is both greater than zero and less than 10.- The expression
evenFlag || n % 3 == 0
istrue
if either condition is true, that is, ifevenFlag
istrue
or the numbern
is divisible by 3. - The ! operator inverts a boolean expression. So
!evenFlag
istrue
ifevenFlag
isfalse
.
In order for an expression with &&
to be true
, both sides of the &&
operator must be true.
In order for an expression with ||
to be false
, both sides of the ||
operator must be false.
The &&
operator can be used to simplify nested if statements.
For example, following code can be rewritten with a single condition.
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");
}
Note
Likewise, the ||
operator can simplify chained if statements. Since the branches are the same, there is no need to duplicate that code.
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");
}
Of course if the statements in the branches were different, we could not combine them into one block. But it’s useful to explore different ways of representing the same logic, especially when it’s complex.
Logical operators evaluate the second expression only when necessary. For example, true || anything is always true, so Java does not need to evaluate the expression anything. Likewise, false && anything is always false.
Ignoring the second operand, when possible, is called short circuit evaluation, by analogy with an electrical circuit. Short circuit evaluation can save time, especially if anything takes a long time to evaluate. It can also avoid unnecessary errors, if anything might fail.
What if you want two things to be true before the body of the conditional is executed? Use &&
as a logical and to join two Boolean expressions and the body of the condition will only be executed only if both are true. For example, what if a child wants to go out and their mom says they can if they clean their room and do their homework? Run the code below and try different values for cleanedRoom
and didHomework
and see what they have to be for it to print You can go out
.
What if it is okay if only one of two things is true? Use ||
as a logical or to join two Boolean expressions and the body of the condition will be executed if one or both are true. For example, your Dad might say you can go out if you can walk or he doesn’t need the car. Try different values for walking
and carIsAvailable
and see what the values have to be to print You can go out
.
The following table (also called a truth table) shows the result for P && Q when P and Q are both expressions that can be true or false. As you can see below the result of P && Q is only true if both P and Q are true.
P | Q | P && Q |
---|---|---|
true | true | true |
false | true | false |
true | false | ? |
false | false | false |
The truth table above is missing one result. What is the result of P && Q when P=true
and Q=false
?
The following table shows the result for P || Q when P and Q are both expressions that can be true or false. As you can see below the result of P || Q is true if either P or Q is true. It is also true when both of them are true.
P | Q | P || Q |
---|---|---|
true | true | true |
false | true | ? |
true | false | true |
false | false | false |
The truth table above is missing one result. What is the result of P || Q
when P=false
and Q=true
?
Check your understanding
- first case
- This will print if both of the conditions are true and they are.
- second case
- This will print either of the conditions are false.
Q-31: What is printed when the following code executes and x has been set to 3 and y has been set to 9?
if (x > 0 && (y / x) == 3) System.out.println("first case");
else System.out.println("second case");
- first case
- This will print if both of the conditions are true, but the second is not.
- second case
- This will print if either of the conditions are false and the second one is (6 / 3 == 2).
Q-32: What is printed when the following code executes and x has been set to 3 and y has been set to 6?
if (x > 0 && (y / x) == 3) System.out.println("first case");
else System.out.println("second case");
Both &&
and ||
use short circuit evaluation. That means that the second condition isn’t necessarily checked if the result from the first condition is enough to tell if the result is true or false. In a complex conditional with a logical and (&&
) both conditions must be true, so if the first is false, then the second doesn’t have to be evaluated. If the complex conditional uses a logical or (||
) and the first condition is true, then the second condition won’t be executed, since only one of the conditions needs to be true.
Note
In a complex conditional using a logical and (&&
) the evaluation will short circuit (not execute the second condition) if the first condition is false. In a complex conditional using a logical or (||
) the evaluation will short circuit if the first condition is true.
Check your understanding
- first case
- This will only print if x is greater than 0 and it is not.
- second case
- This will print if x is less than or equal to zero or if y divided by x is not equal to 3.
- You will get a error because you can't divide by zero.
- Since the first condition if false when x is equal to zero the second condition won't execute. Execution moves to the else.
Q-33: What is printed when the following code executes and x has been set to zero?
if (x > 0 && (y / x) == 3) System.out.println("first case");
else System.out.println("second case");
- first case
- This will print if either of the two conditions are true. The first isn't true but the second will cause an error.
- second case
- This will print if both of the conditions are false. But, an error will occur when testing the second condition.
- You will get a error because you can't divide by zero.
- The first condition will be false so the second one will be executed and lead to an error since you can't divide by zero.
Q-34: What is printed when the following code executes and x has been set to zero? Notice that it is now a logical or (||
) rather than an and (&&
).
if (x > 0 || (y / x) == 3) System.out.println("first case");
else System.out.println("second case");
- first case
- Since x is equal to zero the first expression in the complex conditional will be true and the (y / x) == 3 won't be evaluated, so it won't cause a divide by zero error. It will print "first case".
- second case
- Since x is equal to zero the first part of the complex conditional is true so it will print first case.
- You will get a error because you can't divide by zero.
- You won't get an error because of short circuit evaluation. The (y / x) == 3 won't be evaluated since the first expression is true and an or is used.
Q-35: What is printed when the following code executes and x has been set to zero and y is set to 3?
if (x == 0 || (y / x) == 3) System.out.println("first case");
else System.out.println("second case");
- first case
- Since x is negative the complex conditional will be false and the second condition won't execute. Remember that with
&&
both parts of the condition must be true for the complex conditional to be true. Using a negative substring index won't cause an error since that code will only be executed if x is greater than or equal to zero. - second case
- Since x is negative the second part of the complex conditional won't even execute so the else will be executed.
- You will get a error because you can't use a negative index with substring.
- This would be true if it wasn't using short circuit evaluation, but it is.
Q-36: What is printed when the following code executes and x has been set to negative 1?
String message = "help";
if (x >= 0 && message.substring(x).equals("help") System.out.println("first case");
else System.out.println("second case");
- first case
- The first part of the complex conditional is executed first and will cause a divide by zero error. Complex conditionals are executed from left to right as needed.
- second case
- Since x is equal to zero the evaluation of the first part of the complex conditional will cause a divide by zero error.
- You will get a error because you can't divide by zero.
- Since x is equal to zero the evaluation of the first part of the complex conditional will cause a divide by zero error. You should switch the order of the conditionals to prevent the error because then the first condition would be false and the evaluation would short circuit and not evaluate the second condition.
Q-37: What is printed when the following code executes and x has been set to zero and y is set to 3?
if ((y / x) == 3 || x = 0) System.out.println("first case");
else System.out.println("second case");
-
Drag the definition from the left and drop it on the correct method on the right. Click the "Check Me" button to see if you are correct.
- joins two conditions; is true if both of the conditions are true
- logical and
- a Boolean expression often used to determine if code should be executed or not
- conditional
- an expression that is either true or false
- Boolean expression
- an operator that joins two or more conditions together with logical and's or or's
- logical operator
- used to execute code when one of two conditions is true
- logical or
- one or more statements enclosed in curly braces
- block of statements
- used to evaluate a conditional and execute code if a condition is true
- if
Q-39: Q-38: The following program segment should print either "You can go out" if you don't have any homework and have cleaned and otherwise should print "You can not go out". But the blocks have been mixed up and includes one extra block that is not needed in a correct solution. Drag the needed blocks from the left and put them in the correct order on the right. Click the Check Me button to check your solution.public class Test1
{
public static void main(String[] args)
{
---
boolean haveHomework = false;
boolean cleaned = true;
---
if (!haveHomework && cleaned)
---
if (haveHomework && cleaned) #paired
---
System.out.println("You can go out");
---
else
---
System.out.println("You can not go out");
---
}
}
Q-41: Q-40: The main method in the following class should print if x is in the range of 1 to 10 (inclusive) or not. But, the blocks have been mixed up and includes an extra block that isn't needed in the solution. Drag the needed blocks from the left and put them in the correct order on the right. Click the Check Me button to check your solution.public class Test1
{
public static void main(String[] args)
{
---
int x = 3;
---
if (x >= 1 && x <= 10)
---
if (x >= 1 || x <= 10) #paired
---
System.out.println("1 <= x <= 10");
---
else
---
System.out.println("x is not in range");
---
}
}
Q-43: Q-42: The main method in the following class should print if your favorite food is junk food (pizza or wings) or not. But, the blocks have been mixed up and includes an extra block that is not needed in a correct solution. Drag the needed blocks from the left and put them in the correct order on the right. Click the Check Me button to check your solution.public class Test1
{
public static void main(String[] args)
{
---
String favFood = "kale";
boolean favPizza = favFood.equals("pizza");
boolean favWings = favFood.equals("wings");
---
if (favPizza || favWings)
---
if (favPizza && favWings) #paired
---
System.out.println("You fav is junk food");
---
else
---
System.out.println("You fav is not junk");
---
}
}
Q-45: Q-44: The main method in the following class should print your fine if you are speeding. If you are going over 65 but less than 75 the fine is 50. If you are going at least 75 and less than 85 the fine is 100. Over that the fine is 200. But, the blocks have been mixed up and includes two extra blocks that aren't needed in the solution. Drag the needed blocks from the left and put them in the correct order on the right. Click the Check Me button to check your solution.public class Test1
{
public static void main(String[] args)
{
---
int speed = 90;
---
if (speed > 65 && speed < 75)
---
if (speed > 65 || speed < 75) #paired
---
System.out.println("50");
---
else if (speed >= 75 && speed < 85)
---
else if (speed >= 75 || speed < 85) #paired
---
System.out.println("100");
---
else
System.out.println("200");
---
}
}
Q-47: Q-46: The main method in the following class should print if you can text now. You can text if you are not driving and not eating. But, the blocks have been mixed up and includes an extra block that isn't needed in the solution. Drag the needed blocks from the left and put them in the correct order on the right. Click the Check Me button to check your solution.public class Test1
{
public static void main(String[] args)
{
---
boolean driving = true;
boolean eating = false;
---
if (!driving && !eating)
---
if (!driving || !eating) #paired
---
System.out.println("Can text now");
---
else
---
System.out.println("Can't text now");
---
}
}
Q-49: Q-48: The main method in the following class should print if your name starts with a vowel or not. But, the blocks have been mixed up and there may be an extra block. Drag the blocks from the left and put them in the correct order on the right. Click the Check Me button to check your solution.public class Test1
{
public static void main(String[] args)
{
---
String name = "Julian";
String firstLetter = name.substring(0,1);
String lowerFirst = firstLetter.toLowerCase();
---
boolean aF = lowerFirst.equals("a");
boolean eF = lowerFirst.equals("e");
boolean iF = lowerFirst.equals("i");
boolean oF = lowerFirst.equals("o");
boolean uF = lowerFirst.equals("u");
---
if (aF || eF || iF || oF || uF)
---
if (aF && eF && iF && oF && uF) #paired
---
System.out.println("Starts with a vowel");
---
else
---
System.out.println("Starts with a consonant");
---
}
}