Expressions#
Note
Above, youâll see thereâs a video titled Expressions [Video Walkthrough]. The video and the reading both have the same information! Youâre not required to go through both the video and the reading, as the video just walks through the reading to help contextualize it!
đ˘ Expressions#
By now, youâve worked a bit with data types such as int
, double
, String
, and boolean
. In this lesson, weâll learn about how else we can use these values!
Specifically, now that we can have notions of 5
and 3.14
in our programs, something you may be inclined to do is write a simple mathematical expression such as 5 + 3.14
. Good news! Java knows about math, and works the way you might expect! (For the most part⌠more to come on this a bit further down the page.)
â Operators#
The basic mathematical operators for addition (using +
), subtraction (using -
), multiplication (using *
), and division (using /
) are available in Java. Each of these mathematical operators are binary operators, meaning they are used to combine two values (or operands) and each operation evaluates to a new value.
Letâs take a look at a few examples! Youâll see a code snippet below with expressions inside of System.out.println
statements. Each expression evaluates to a resulting value, which is then printed out using the println
statements!
public class ExpressionPractice{
public static void main(String[] args) {
System.out.println(3 + 5);
System.out.println(6.9 + 1.145);
System.out.println(5 * 10);
System.out.println(18.5 / 2.5);
System.out.println(10 / 3);
}
}
Hit the âRunâ button and take a look at the output. Are all of the results that are printed what you expected? Take a close look at the last lineâŚđ¤ huh? (keep reading âŹď¸)
â Integer Division#
The basic mathematical operators work as you would expect, except for the division operator when working with two int
operands. In the 10 / 3
example shown above, you may have expected to see something like 3.333
, but instead we see that the result evaluates to 3
. In this scenario, âint divisionâ or âtruncating divisionâ is performedâ-you can instead think of this as answering the question of âHow many times does 3 fit evenly into 10?â where the answer is 3. Alternatively, you can do mathematical division and get an answer of 3.333
⌠, then remember that in this case we truncate everything to the right of the decimal point, giving us the final answer 3
.
Caution
Forgetting about integer division when working with int
s is a very common source of bugs (bugs are coding errors in programs) when youâre first starting out (and frequently comes back to haunt even the most experienced programmers).
If youâre noticing some strange 0
âs showing up where they shouldnât or some of your numerical results look off, check anywhere youâre using division to make sure youâre getting the results you expect! đđ
đ˛ Modulo or âModâ (%)#
Java actually provides another mathematical operator that you may not have seen before: the modulo (or âmodâ for short) operator, which uses the %
character. This operatorâs result is what would be the remainder of an int
division using the same two operands. For example, if we were to evaluate 10 % 3
, we would get s
which is the remainder we get when evaluating 10 / 3
. Given this description, what do you expect 4 % 2
âs result to be? Take a moment to think before running the code below:
public class ModuloPractice {
public static void main(String[] args) {
System.out.println(10 % 3);
System.out.println(4 % 2);
System.out.println(2 % 6);
}
}
𧾠Dealing with Strings#
So far weâve only been talking about int
and double
types, but youâve also been working with values of type String
! String
values arenât able to work with the *
, -
, /
, or %
operators (if you try to use them, you will get a compiler error), but they do work with +
! When dealing with String values, +
denotes concatenation which is a fancy way of saying âsquishing String
s togetherâ! Try running the code below to understand how String
concatenation works!
public class ConcatenationPractice {
public static void main(String[] args) {
System.out.println("Hello " + "everyone!");
System.out.println("Java i" + "s so co" + "ol");
}
}
âď¸ Relational and Logical Operators#
Relational operators allow us to check the relationship between two operands (or values). We evaluate the expression using the relational operators to see if that relationship is true
or false
. Some of the basic relational operators can be seen below:
Operator | Description | Example |
---|---|---|
== |
equal to | 3 == 9 returns false |
!= |
not equal to | 3 != 9 returns true |
> |
greater than | 10 > 5 returns true |
< |
less than | 7 < 3 returns false |
>= |
greater than or equal to | 2 <= 2 returns true |
<= |
less than or equal to | 10 <= 5 returns false |
Alongside relational operators, we also have logical operators. Just like relational operators, they evaluate some expression to either true
or false
. But we can use logical operators to combine two or more boolean
expressions or to get the opposite value of a particular boolean
expression! Check out some logical operators below:
Operator | Syntax | Description | Example |
---|---|---|---|
&& (logical AND) |
expression1 && expression2 |
returns true if both expressions evaluate to true |
8 > 4 && 14 != 7 |
|| (logical OR) |
expression1 || expression2 |
returns true if at least one of the expressions evaluates to true |
8 % 2 == 0 || -8 < 0 |
! (logical NOT) |
!expression |
returns true if the expression is false and vice versa |
!(8.5 < -9.716) |
đ¤ Expressions Using Different Types#
Weâve notably only trying out examples where both of the operands share the same type. What do you think would happen if we tried to use these operators using values of different types in an expression? Take a moment to think about some reasonable things Java could do given this scenario before clicking âExpandâ below!
Expand
Java will *convert* one of the operands to the other operand's type, then it will perform the operation! Here are how the conversions work:ints can be converted to doubles
e.g., 5.0 * 2 âĄď¸ 5.0 * 2.0
ints can be converted to Strings
e.g., 5 + âhelloâ âĄď¸ â5â + âhelloâ
doubles can be converted to Strings
e.g., âpickleâ + 4.9 âĄď¸ âpickleâ + â4.9â
You can think of these conversion rules like a waterfall: when two types are involved in an operation, the one higher up in the waterfall overtakes the one lower down!
Danger
You cannot combine values of type boolean with other types in an expression! Java will give you a compiler error if you try.
đ Precedence (Order of Operations)#
Now that weâve got a grasp of the basics, letâs think about some more complicated expressions. When there are multiple operators involved in an expression (like 3 * 14.5 + 6 + "hi"
) you have to think about precedence, or what order the parts of the expression (or subexpressions) are evaluated in. The PEMDAS order-of-operations trick that you may have learned in earlier school years applies here (with a few small tweaks) for non-boolean expressions.
**[P]**arentheses (
()
) - You can use parentheses in a Java expression in the same way that you can in a mathematical expression. Any subexpression that is inside of parentheses is performed before any other part of the expression.[
EM M D]EModulo (%
) - There isnât a Java operator for âexponentsâ (^
actually does something different), but we can instead replace this with the mod operator.Multiplication (
*
)Division (
/
)
[A S]
Addition (
+
) - This really applies to the+
operator, so both addition andString
concatenation share this level of precedence!Subtraction (
-
)
đ Levels of Precedence#
Notice that weâve grouped mod, multiplication, and division together, and addition and subtraction have their own group. These groupings indicate the levels of precedence. In other words, all of the operators within a level of precedence donât have priority over the othersâin Java, when there are multiple subexpressions with the same level of precedence, they are executed from left to right.
Caution
In classical mathematics, the order of doing multiplication and division in an expression didnât matter - the result would be the same. However, because in Java we are dealing not only with each subexpressionâs resulting value, but also its resulting type, the order of evaluation does matter!
â Precedence with boolean
s#
All of the operators discussed above (PMMDAS) have higher precedence than the relational and logical operators weâve introduced except for the âlogical NOTâ operator (!
). So specifically, the full list in their order of precedence, we have:
Logical NOT
!
Parentheses
()
Mod, Multiplication, and Division
%
,*
,/
Addition and Subtraction
+
,-
Relational operators
<
,>
,<=
,>=
(at the same level of precedence)Relational operators
==
,!=
(at the same level of precedence)Logical AND
&&
Logical OR
||
So you can generally evaluate any logical NOT operators, then perform all of the non-Boolean operations according to the PMMDAS precedence described above, and then evaluate each of the subexpressions involving relational operators (<
, >
, <=
, >=
before ==
and !=
), then the subexpressions involving logical AND &&
, and finally any remaining subexpressions involving logical OR ||
. As described above, when there are multiple subexpressions with the same level of precedence, they are executed from left to right.
Try running the code below to understand how these different operators work when used together!
public class BooleanOperators {
public static void main(String[] args) {
System.out.println("5 < 20: " + (5 < 20));
System.out.println("29.8 == 14825.7942: " + (29.8 == 14825.7942));
System.out.println("18 % 2 != 0: " + (18 % 2 != 0));
System.out.println("-6 < -6: " + (-6 < -6));
System.out.println("-6 <= -6: " + (-6 <= -6));
System.out.println("5 < 20 && -6 <= -6: " + (5 < 20 && -6 <= -6));
System.out.println("5 < 20 && -6 < -6: " + (5 < 20 && -6 < -6));
System.out.println("5 < 20 || -6 <= -6: " + (5 < 20 || -6 <= -6));
System.out.println("5 < 20 || -6 < -6: " + (5 < 20 || -6 < -6));
System.out.println("!(7.162 >= 7): " + !(7.162 >= 7));
}
}
Main Points:#
Java can combine data into expressions - many mathematical operators work as you expect (+, -, /, *, <, >).
There are additional operators that Java supports that you may not be familiar with (e.g., %, ==, !=, <=, >=, &&, ||, !).
When evaluating Java expressions, you also need to keep track of the types that are involved in each subexpression, as they sometimes affect how operators behave (e.g., int division).
Java obeys strict rules about precedence, and when there are multiple operators in an expression at the same level of precedence, subexpressions are evaluated in order from left to right.
Java levels of precedence: [!] [P] [MMD] [AS] [<><=>=] [== !=] [&&] [||]