- Explain logical operators.
- Discuss Truth Tables.
- Discuss De Morgan's Laws.
- Learn about compound conditionals.
Logical operators allow us to compare boolean values against each other. Just like we can compare numerical values with relational operators, logical operators do the same except with true/false values. The result of logical operators will always be a boolean, just like relational operators! Let's look at two boolean expressions:
int firstNumber = 20;
int secondNumber = 10;
boolean expression1 = firstNumber > secondNumber;
boolean expression2 = firstNumber != 20;
Now that we have two boolean expressions we can compare, we still have to ask "How do we compare these two expressions?" Consider the following table of logical operators:
Operator | Description |
---|---|
&& |
AND |
|| |
OR |
! |
NOT |
^ |
XOR |
Let's break this down and explain what each operator means in this table:
&&
(AND) returns true if and only if both sides of the binary operator are true, so:expression1
evaluates to true.expression2
evaluates to false.- Therefore,
expression1 && expression2
is synonymous totrue && false
. - Since the value true is not on both sides of the operator, the logical expression would return false.
||
(OR) returns true if either side of the binary operator is true, so:expression1
evaluates to true.expression2
evaluates to false.- Therefore,
expression1 || expression2
is synonymous totrue || false
. - Since the value true is on at least one side of the operator, the logical expression would return true.
!
(NOT) is a unary operator that returns the reverse of its single operand, so:expression1
evaluates to true.- Therefore,
!expression1
is the same as!true
. - Well, the opposite of "not true" is false. So the logical expression,
!expression1
would return false.
^
(XOR) pronounced "exclusive or" or "x-or" returns true if and only if both sides of the binary operator are different.expression1
evaluates to true.expression2
evaluates to false.- Therefore,
expression1 ^ expression2
is the same astrue ^ false
. - Since the boolean values are different, the logical expression would return true.
Logical operators are helpful and often used within conditional clauses. It would be nice to have a tool though to help us quickly evaluate these logical expressions. This is where truth tables are helpful!
A truth table is a tabular representation of input and output combinations. We can create truth tables for all of our logical operators, so we know what each combination would return. This tool is helpful for us to look back on when we may be unsure what an expression should return.
For each of these truth tables, consider X to be the first input and Y to be the second input (when appropriate) where both X and Y are boolean values.
X | Y | X && Y |
---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
A note about the &&
operator is that it makes use of the short-circuit effect.
This means, that if the left-hand operand is false, then the expression will
immediately return false without looking at the right-hand operand.
X | Y | X || Y |
---|---|---|
true | true | true |
true | false | true |
false | true | true |
false | false | false |
The ||
operator also makes use of the short-circuit effect, but does so a
little differently than the &&
operator. For the ||
operator, if the
left-hand operand is true, then the expression will immediately return true
without looking at the right-hand operand.
X | !X |
---|---|
true | false |
false | true |
X | Y | X ^ Y |
---|---|---|
true | true | false |
true | false | true |
false | true | true |
false | false | false |
Mathematician, Augustus De Morgan, came up with a few laws regarding negating sets that we can apply to our logical operators.
These laws state the expression
!(condition1 && condition2)
is logically equivalent to the expression!condition1 || !condition2
. Also, the expression!(condition1 || condition2)
is logically equivalent to!condition1 && !condition2
.
Java How To Program (Early Objects), Tenth Edition
Consider the following:
boolean p = true;
boolean q = true;
boolean expression = !(p || q);
System.out.println(expression);
Notice the expression
variable is set to !(p || q)
. Using the values of p
and q
, we can see that p || q
results in true
. But when we negate true
with the !
operator, it evaluates the expression to false
.
According to De Morgan's Law, !(p || q)
is equal to !p && !q
. Let's check!
!p
would be equivalent to !true
, or false
. Since the first condition (or
the left-hand operand) evaluates to false
, we don't even need to evaluate !q
since anything &&
together with a false
value will immediately return
false
.
Similarly, we could have this expression:
boolean p = true;
boolean q = true;
boolean expression = !(p && q);
System.out.println(expression);
The expression
variable is now set to !(p && q)
. Using the values of p
and
q
, we can see that p && q
results in true
. But when we negate true
with
the !
operator, it turns to be false
.
Per De Morgan's Law, the equivalent of this expression is !p || !q
.
Now what happens when we have an expression like this:
int a = 0;
int b = 1;
boolean expression = !(a > 5 && b < 10);
System.out.println(expression);
We know that, per De Morgan's law, the &&
would turn into a ||
when we
negate this expression. But what about the operators in the expressions
a > 5
and b < 10
? Consider the following table of what happens when each
operator is negated:
operator | !operator |
---|---|
< |
>= |
> |
<= |
<= |
> |
>= |
< |
== |
!= |
!= |
== |
So if we wanted to write the equivalent expression to !(a > 5 && b < 10)
we
can use the table here and what we have leaned to turn this into
a <= 5 || b >= 10
.
The video here walks through De Morgan's Laws with some more examples if you are interested: DeMorgans Law Java