Operators
This section introduces you to the Java operators. The utility of many of them may not be obvious at this point, but it will be good to know the range of operators you have available to you.
Arithmetic operators
Java includes the expected operators for addition, subtraction, multiplication, and division.
+ - * /
There is one important aspect of the division operator that you need to learn right away: it behaves differently for floating-point types as it does for integer types.
1.0/2.0 ⇒ 0.5
(⇒ means “evaluates to.”) But:
1/2 ⇏ 0.5
⇏ means “does not evaluate to.”) Instead:
1/2 ⇒ 0
Why? Keep reading.
Integer division and Modulus
When both operands are integer types (byte, short, int, or long), division (known specifically as “integer division”) returns only the number of times the divisor goes into the dividend. Any remainder is discarded. So
1/2 ⇒ 0 and 5/2 ⇒ 2
112/25 ⇒ 4
If you want the remainder, you can use the modulus operator, %:
5 % 2 ⇒ 1
112 % 25 ⇒ 12
See below for a common use of the % operator.
Relational operators
There are six relational operators: < (less-than), <= (less than or equal to), > (greater than), >= (greater than or equal to), and == (equals) and != (not equals).
Here's an expression that evaluates to true if the number n is even, and false if n is odd:
n % 2 == 0
Logical operators
Logical operators operate on boolean values. There are three: && (AND), || (OR), and ! (NOT). ! is defined as follows:
!true ⇒ false and !false ⇒ true
&& and || are defined in the truth table shown in Table Truth table for && and ||:
| x | y | x && y | x || y |
|---|---|---|---|
| false | false | false | false |
| false | true | false | true |
| true | false | false | true |
| true | true | true | true |
The relational operators are often combined with the logical operators. For example, to code something like 21 < age ≤ 65, you would need to write something like:
21 < age && age <= 65
Ternary operator
“Ternary” means “has three parts.” Here's the general form:
bool-expr ? value-if-true : value-if-false
If bool-expr is true, the result of the operator is value-if-true; if false, the result is value-if-false.
true ? x : y ⇒ x
false ? x : y ⇒ y
String concatenation operator
The + operator, applied between two String objects, concatenates the two strings:
"tooth" + "pick" ⇒ "toothpick"
A convenient feature of string concatenation is that when either side of the operator is a string, Java will automatically convert the other side to a string (Java knows how to convert any primitive type to a string), and then concatenate the two strings. So:
1 + "st" ⇒ "1st"
Assignment operators
We introduced the assignment operator = as a way to copy a value into a variable. It's a little more complicated than that. The assignment operator also yields the value of the RHS. That makes possible statements such as this:
x = y = z = 1;
This can be understood as:
x = (y = (z = 1));
After this statement is executed, x, y, and z have the value 1.
Compound assignment operators
When using a variable as a counter, a typical operation is to add 1 to the variable when whatever it is that you are counting happens. Then you may use an assignment statement such as this:
counter = counter + 1;
Or perhaps you are sampling every tenth element of a list. Then you might have an assignment statement such as this:
i = i + 10;
Java's compound assignment operators offer shorthand ways of doing this very common operation. Table Frequently used compound assignment operators shows two of the most commonly used.
| Operator | Example | Same as |
|---|---|---|
| += | x += 10 | x = x + 10 |
| -= | x -= rowLength | x = x - rowLength |
There are also compound assignment operators for * (*=), / (/=), and % (%=).
You may be wondering what is the point of these operators, since they only save two or three characters from the expression. Without asking the designers of the Java language it is difficult to know precisely why they were included, but what is certain is that programmers like them, so that may be the more important question. We believe programmers like them because they are slightly closer to being a direct expression of the programmer's intent than the longer form. If I mean “make the value of x bigger by 10”, x += 10; expresses this a little better than x = x + 10;.
Increment and decrement operators
Counter variables that count up or down by 1 are far the most common, so Java offers operators for these two specific cases. They are the ++ (increment) and – (decrement) operators, and each come in two forms: one where the operator is placed after the variable (“post”) and the other where the operator is placed before the variable (“pre”).
| Usage | Name | Effect | Result returned |
|---|---|---|---|
| i++ | Post-increment | Increases the value of x by 1 | i |
| i‐‐ | Post-decrement | Decreases the value of x by 1 | i |
| ++i | Pre-increment | Increases the value of x by 1 | i + 1 |
| ‐‐i | Pre-decrement | Decreases the value of x by 1 | i - 1 |
When these are used as standalone statements, there is no difference between the pre- and post- forms. But when used within expressions, then care must be taken to use the correct form. If you want the value of x before it is incremented, then use the post form (x++); if you want the value of x after it is incremented, then use the pre form (++x); similarly with decrement.
Type conversion and casting
Sometimes we need to convert a value of one type to a value of another type. Java will do this implicitly when the conversion can be done without loss of information. Values of type float (32 bits) will be converted to values of type double (64 bits) without issue. So this statement—double d = 2.0F;—is fine. But this statement—float f = 2.0D;— would be rejected by the Java compiler. (“F” signifies a float literal, “D” signifies a double literal.)
So what do you do when you need to do a “lossy” conversion? An example of when you might need to do this is when you need to avoid integer division (see above). Suppose we have the number of minutes someone has worked, and we want to know how many hours they've worked. We know the number of hours will be some number with a decimal point, so we declare it to be a float.
int minutesWorked = 295; float hoursWorked = minutesWorked / 60;
The result in hoursWorked will be 4.0, but the true result would be 4.9166665, which would make quite a difference in somebody's pay. The reason is that when evaluating minutesWorked / 60, Java is performing integer division, which discards any remainder (anything after the decimal point).
You can force a conversion by casting. You cast a value from one type to another through a cast operator, which is simply a type name surrounded by parentheses: ( type-name ). Here's how to use it to solve the issue above:
int minutesWorked = 295; float hoursWorked = ((float) minutesWorked) / 60;
The expression (float) minutesWorked evaluates to the floating-point value 295.0, which forces the division to be floating-point division, which is what we need.