Unit 2 · 20 min
2.6 Comparing Boolean Expressions
Equivalent expressions always agree, and == on objects asks about identity, not contents.
Summary, objectives and course and exam description (CED) codes
Two Boolean expressions are equivalent if they evaluate to the same value in all cases, and a truth table can prove it. De Morgan's laws create equivalent expressions: !(a && b) is equivalent to !a || !b, and !(a || b) is equivalent to !a && !b. For objects, == and != compare object references (including checks against null), while a class's equals method compares objects using their attributes.
By the end of this session you can
- 2.6.A Compare equivalent Boolean expressions.
- 2.6.B Develop code to compare object references using Boolean expressions and determine the result of these expressions.
Reviewed against the CED on
1LearnThe notes, the traps and how to remember them
1. Equivalent expressions and truth tables
Two Boolean expressions are equivalent if they evaluate to the same value in all cases. A truth table can prove they are equivalent 2.6.A.1: list every combination of true and false for the variables, evaluate both expressions in each row, and compare. With two variables there are 4 rows; with three variables there are 8.
Are !(a && b) and !a || !b equivalent?
| a | b | a && b | !(a && b) | !a | !b | !a || !b |
|---|---|---|---|---|---|---|
| true | true | true | false | false | false | false |
| true | false | false | true | false | true | true |
| false | true | false | true | true | false | true |
| false | false | false | true | true | true | true |
The columns for !(a && b) and !a || !b match in every row, so the expressions are equivalent.
Are !(a && b) and !a && !b equivalent? Row 2 (a true, b false) gives true for the first and false for the second. One row that differs is enough to show two expressions are not equivalent.
boolean a = true;
boolean b = false;
System.out.println(!(a && b));
System.out.println(!a || !b);
System.out.println(!a && !b);
Output:
true
true
false
2. De Morgan’s laws
De Morgan’s laws can be applied to Boolean expressions to create equivalent Boolean expressions 2.6.A.2:
!(a && b)is equivalent to!a || !b!(a || b)is equivalent to!a && !b
To apply a law: move the ! onto each part, and switch && to || (or || to &&). When the parts are comparisons, negate each comparison:
| Comparison | Its negation |
|---|---|
x > 5 |
x <= 5 |
x < 5 |
x >= 5 |
x >= 5 |
x < 5 |
x == 5 |
x != 5 |
Example: !(temp > 30 || isRaining) becomes temp <= 30 && !isRaining. In words: “not (hot or raining)” means “not hot and not raining”.
int temp = 24;
boolean isRaining = false;
boolean original = !(temp > 30 || isRaining);
boolean rewritten = temp <= 30 && !isRaining;
System.out.println(original + " " + rewritten);
Output:
true true
Watch out: a common wrong answer keeps the > and writes temp < 30. For temp equal to 30, !(temp > 30) is true but temp < 30 is false.
3. Two variables, one object
Two different variables can hold references to the same object. Object references can be compared using == and != 2.6.B.1. The comparison is true only when both references point to the same object; it does not look at what is inside the objects.
String teamA = new String("Lions");
String teamB = new String("Lions");
String favorite = teamA;
System.out.println(teamA == favorite);
System.out.println(teamA == teamB);
System.out.println(teamA != teamB);
Output:
true
false
true
| Variable | Refers to |
|---|---|
teamA |
object 1 (“Lions”) |
favorite |
object 1 (same object as teamA) |
teamB |
object 2 (“Lions”, a separate object) |
Variables like teamA and favorite, which refer to the same object, are called aliases.
Watch out: two string literals with the same characters, such as "Lions" and "Lions", may share one object, so == can happen to be true. Never rely on this: compare string contents with equals.
4. Comparing a reference with null
A reference variable can hold null, which means it does not refer to any object. Comparing a reference with null, using == or !=, tells you whether it actually refers to an object 2.6.B.2.
String winner = null;
if (winner == null) {
System.out.println("No winner yet");
}
winner = "Tigers";
if (winner != null) {
System.out.println("Winner: " + winner + " (" + winner.length() + " letters)");
}
Output:
No winner yet
Winner: Tigers (6 letters)
Calling a method such as length() on a null reference throws a NullPointerException. Check for null first, and put that check on the left of && so short-circuit evaluation protects the call: winner != null && winner.length() > 2.
5. equals: equivalency by attributes
Classes often define their own equals method to specify what makes two objects of that class equivalent. The decision is most often based on attributes of the two objects 2.6.B.3.
The String class is the example you use most. Its equals method treats two strings as equivalent when they have the same sequence of characters, even if they are separate objects.
String typed = new String("open sesame");
String password = "open sesame";
System.out.println(typed == password);
System.out.println(typed.equals(password));
System.out.println(typed.equals("Open sesame"));
Output:
false
true
false
Uppercase and lowercase letters are different characters, so the last comparison is false.
Other classes choose their own criteria. A class for library cards might call two cards equal when their card numbers match; a class for points on a grid might compare both coordinates. When an exam question gives you a class with an equals method, read its description to see which attributes it compares. (Writing your own replacement for the equals method is outside the AP® course and exam.)
| Question you are asking | Use |
|---|---|
| Do these two variables refer to the same object? | == |
| Does this variable refer to any object? | == null or != null |
| Are these two objects equivalent (same attribute values)? | equals |
Lock it in: memory hooks
- De Morgan's lawsBreak the line, change the sign: push the ! inside, flip && and ||.
- Negating comparisons> becomes <=, < becomes >=, == becomes !=. The equals part always switches sides.
- == versus equals== asks "same object?"; equals asks "same contents?"
Common misconceptions
"!(a && b) is the same as !a && !b."
Not quite. De Morgan's law flips the operator: !(a && b) is equivalent to !a || !b. Check with a = true, b = false: !(true && false) is true, but !a && !b is false.
"The opposite of x > 5 is x < 5."
Not quite. The opposite of x > 5 is x <= 5. The value 5 itself makes x > 5 false, so it must make the negation true.
"If two variables hold equal-looking objects, == is true."
Not quite. == asks whether two references refer to the same object. Two separate objects with the same attribute values are not ==, but they can be equal according to the class's equals method.
Exam traps
- Negating a comparison: !(score >= 60) is score < 60, not score <= 60.
- !(a && b) is not !a && !b. The operator must flip.
- One test case is not a proof of equivalence. Check every row of the truth table.
- Calling a method on a null reference throws a NullPointerException. Check != null first, on the left of &&.
2PracticeRecall it, then check yourself
In 30 seconds
- Equivalent Boolean expressions give the same value in every case. A truth table that checks every combination proves it.
- De Morgan: !(a && b) equals !a || !b, and !(a || b) equals !a && !b.
- Two variables can hold references to the same object (aliases). == and != compare references.
- Compare a reference with null (== null or != null) to check whether it refers to an object.
- A class's equals method defines equivalency, usually by comparing attributes, such as the characters of two strings.
Cover this list, say the points out loud, then take the checkpoint without scrolling back up.
Checkpoint · 6 questions
Checkpoint: Comparing Boolean Expressions
Pick an answer to mark it. Every answer is explained, and you can try any question again. Your saved score counts first tries only, and stays in this browser.
3PrevailLock it in for exam day
By the numbers
- De Morgan's laws two laws CED 2.6.A.2
- !(a && b) is equivalent to !a || !b
- !(a || b) is equivalent to !a && !b
- Ways to compare objects three ways CED 2.6.B.1, 2.6.B.2, 2.6.B.3
- == or != between two referencessame object or not
- == or != with nulldoes the reference refer to an object
- equalsare the objects equivalent, usually by their attributes
Key terms: flip the cards
Read the term, say the definition out loud, then flip to check. Struggling a little to remember is what makes it stick.
-
Equivalent Boolean expressionstap to flip
Two Boolean expressions that evaluate to the same value in all cases. A truth table can prove they are equivalent.
Example and CED codes -
Truth tabletap to flip
A table that lists every combination of true and false for the variables in Boolean expressions, with the value of each expression in every row.
Example and CED codes -
De Morgan's lawstap to flip
Rules that create equivalent Boolean expressions: !(a && b) is equivalent to !a || !b, and !(a || b) is equivalent to !a && !b.
Example and CED codes -
Logical operatorstap to flip
The operators ! (not), && (and) and || (or), which combine Boolean expressions into a compound Boolean expression. Precedence: !, then &&, then ||.
Example and CED codes -
Reference equality (== versus equals)tap to flip
Using == or != on object references checks whether they refer to the same object. A class's equals method checks whether two objects are equivalent.
Example and CED codes -
Object referencetap to flip
The value a reference variable holds: it can be thought of as the memory address of the object.
Example and CED codes -
nulltap to flip
A special literal meaning a reference variable is not associated with any object.
Example and CED codes
Questions students ask
What are De Morgan's laws in Java?
!(a && b) is equivalent to !a || !b, and !(a || b) is equivalent to !a && !b. To apply them, negate each part and switch && with ||.
How do you prove two Boolean expressions are equivalent?
Build a truth table with every combination of true and false for the variables. If both expressions give the same value in every row, they are equivalent.
What is the difference between == and equals for objects?
== compares object references, so it is true only when both refer to the same object. equals compares the objects by the criteria the class defines, usually their attributes.
How do I check if an object reference is null?
Compare it with null using == or !=, for example if (name != null). Never call a method on a reference before checking it is not null.