Unit 3 - Booleans and If-Statements
Boolean Expressions and Operators
A Boolean expression is a mathematical expression that evaluates to either true or false.
Boolean expressions are commonly used in
ifstatements to control the flow of execution.
Relational Operators
Equality (
==): Checks if two primitive values are equal.- Example:
3 == 2(evaluates tofalse) - Only use double equals with primitive types; objects require a different approach.
- Example:
Inequality (
!=): Checks if two values are not equal.- Example:
3 != 2(evaluates totrue)
- Example:
Other relational operators:
- Greater than:
> - Less than:
< - Greater than or equal to:
>= - Less than or equal to:
<=
- Greater than:
Example:
x <= 2(wherexis a variable)
Conditional Operators
Conditional operators combine two or more Boolean expressions.
AND (
&&): Both expressions must be true for the combined expression to be true.Example:
x <= 4 && x < 3Short-circuiting: If the first expression is false, the second expression is not evaluated.
Significance: Prevents errors if the second expression might cause a crash.
- Example:
5 / 0 > 3will cause anArithmeticException, butfalse && (5 / 0 > 3)will not due to short-circuiting.
- Example:
OR (
||): Either expression must be true for the combined expression to be true.Example:
x > 3 || x == 10Short-circuiting: If the first expression is true, the second expression is not evaluated.
Significance: Prevents errors if the second expression might cause a crash.
- Example:
true || (5 / 0 > 3)will not cause an error due to short-circuiting.
- Example:
If, Else If, and Else Statements
- These statements control the execution of code blocks based on Boolean expressions.
ifandelse ifrequire a Boolean expression.elsedoes not require a Boolean expression.else ifandelsemust have anifor anotherelse ifto be associated with.
If Statements
ifstatements are independent unless nested.Multiple
ifstatements can execute in a sequence.Example:
int x = 5; if (x < 10) { // true System.out.println("a"); // Executes } if (x < 4) { // false System.out.println("b"); // Skips } if (x < 7) { // true System.out.println("c"); // Executes }
Else Statements
elseprovides an alternative block of code to execute when theifcondition is false.Example:
int y = 5; if (y > 10) { // false System.out.println("d"); // Skips } else { System.out.println("e"); // Executes }
Else If Statements
else ifprovides multiple conditions to check in sequence.If an
iforelse ifcondition is true, its block executes, and the rest are skipped.If no condition is true, the
elseblock executes (if present).Example:
int z = 5; if (z > 10) { // false System.out.println("f"); // Skips } else if (z >= 4) { // true System.out.println("g"); // Executes } else { System.out.println("h"); // Skips }
Single-Line Code Blocks
Curly brackets are optional for
if,else if, andelseif the block contains only one line of code.Indentation is used to indicate the code's association with the conditional statement.
Example:
if (x > 0) System.out.println("Positive");
Common Mistakes
Adding a semicolon after the
if,else if, orelsestatement.- This disconnects the intended code block from the conditional statement, leading to unexpected behavior or compiler errors (e.g., "
elsewithoutif").
- This disconnects the intended code block from the conditional statement, leading to unexpected behavior or compiler errors (e.g., "
Attaching a Boolean expression to an
elsestatement (onlyifandelse ifneed conditions).Forgetting curly brackets for multi-line code blocks in
if,else if, orelsestatements.
Nested If, Else If, and Else Statements
if,else if, andelsestatements can be nested inside other conditional blocks.Other control structures (e.g.,
while,for) can also be nested.Example:
if (x < 10) { if (y != 3) { System.out.println("a"); } else if (y <= 5) { System.out.println("b"); } else { System.out.println("c"); } } else { if (x == 10) { System.out.println("d"); } else if (x > 10) { System.out.println("e"); } }Tracing nested conditionals requires careful attention to the Boolean expressions and their associated blocks.
De Morgan's Laws
De Morgan's laws provide equivalencies for negating compound Boolean expressions.
Law 1: NOT (A \text{ OR } B) \equiv (NOT A) \text{ AND } (NOT B)
Law 2: NOT (A \text{ AND } B) \equiv (NOT A) \text{ OR } (NOT B)
In Java (and many other languages):
NOTis represented by!ANDis represented by&&ORis represented by||
Equivalents for Booleans:
!(A && B)is equivalent to!A || !B!(A || B)is equivalent to!A && !B
Equivalents including numbers:
!(A == B)is equivalent toA != B!(A > B)is equivalent toA <= B!(A >= B)is equivalent toA < B
Example: Simplify
!(a > b || b != a)- Apply De Morgan's law:
!(a > b) && !(b != a) - Simplify:
a <= b && b == a
- Apply De Morgan's law:
For complex expressions with nested parentheses:
- Apply De Morgan's laws level by level, starting from the outermost parentheses.
- Example: Simplify
!(a == b || !(b >= c || a < c)) -> (a != b && !(b >= c || a < c)) -> (a != b && (b < c && a >= c))
Checking Equality of Different Data Types
- Primitive data types (e.g.,
boolean,char,byte,short,int,long,float,double) can be compared using the double equals operator (==). - Reference/Object types need different methods since using
==will only check if they point to the same object in memory.
Primitive Data Types
Example:
int a = 3; int b = 3; double c = 3.0; double d = 3.0; boolean e = false;Boolean expressions:
a == b(true becauseaandbhave the same value)a != b(false becauseaandbare equal)c == 3.0(true becausechas the value 3.0)a == d(true becauseais implicitly converted to a double for comparison)c == e(Error because Java cannot directly compare numerical values to boolean values.
Object Types
Using
==compares if two reference variables point to the same object.The
equals()method can perform a 'deep' comparison, checking if the data within the objects is equivalent.- Some classes implement
equals()as a shallow comparison (same as==). - Other classes implement
equals()as a deep comparison (checking data equivalence).
- Some classes implement
Strings
Strings can be declared in two ways:
Using string literals (e.g.,
String a = "coffee";)- String literals are stored in a string pool on the heap.
- If an equivalent string already exists in the pool, the new variable will point to the existing string.
Using the
new String()constructor (e.g.,String c = new String("coffee");)- Creates a new string object outside the string pool.
Examples:
String a = "coffee"; String b = "coffee"; String c = new String("coffee");Boolean expressions:
a == b(true becauseaandbpoint to the same string in the string pool)a == c(false becauseaandcpoint to different objects on the heap even though they contain the same value)a.equals(b)(true because theequals()method for strings does a deep comparison)a.equals(c)(true because theequals()method compares the contents, not the object references)
Best Practices
- Use
==and!=to compare primitive data types. - Use the
equals()method to compare objects when a deep comparison is needed. - Be aware of whether the
equals()method performs a shallow or deep comparison for a given class. - Use specialized methods (e.g.,
Arrays.equals()) for comparing specific object types like arrays.