Comparing Boolean Expressions (De Morgan's Laws)
De Morgan's Laws
Negating a compound condition flips both the operator and each individual comparison:
!(a && b) is equivalent to !a || !b
!(a || b) is equivalent to !a && !b
A simple way to remember it: push the ! inward, and flip && to || (or || to &&) as it moves in.
Flipping Relational Operators Under Negation
The same idea applies to relational operators — negating a comparison flips its sign:
!(c == d) is c != d
!(c < d) is c >= d
!(c > d) is c <= d
Putting both rules together: !(x < 3 && y > 2) becomes !(x < 3) || !(y > 2), which simplifies further to (x >= 3 || y <= 2).
Why Bother Simplifying
!(ready && armed) and !ready || !armed always evaluate to the same result — but the second one reads more directly as "either one isn't ready" instead of "it's not true that both are ready." Simplifying a negated condition often makes the code's actual intent clearer.
if (!ready || !armed) {
abort();
}
A Preview: Comparing Objects
== on objects (a preview from Lesson 5.4) compares whether two variables point at the same object, not whether their contents match. This matters for Strings specifically, which get their own full treatment in Ch.6 — for now, the short version: use .equals() to compare what two objects actually contain, and reserve ==/!= for checking against null.
if (sensor != null && sensor.isFaulty()) { ... } // == used correctly, against null
Common Pitfalls
- Forgetting to flip the operator, not just add a
!.!(x < 3)isx >= 3, notx !< 3(which isn't valid Java) and notx > 3(which misses the equal case). - Applying De Morgan's Law only to one side. Both the operator (
&&/||) and both individual comparisons flip — doing only one produces a wrong, non-equivalent expression.
Key Takeaways
!(a && b)is equivalent to!a || !b;!(a || b)is equivalent to!a && !b.- Negating a relational operator flips its sign:
<becomes>=,>becomes<=,==becomes!=. - Simplifying a negated condition often makes its intent easier to read, even though it's logically equivalent either way.
==on objects checks identity, not content —.equals()(covered fully in Ch.6) is for comparing what's actually inside.
Derived from csawesome-2026: unit-2-selection-and-iteration/2.06-comparing-boolean-expressions-de-morgan-s-laws.md (CSA 2.6)