Java Operators

Operators

 

Java provides a rich operator environment. Most of its operators can be divided into the following four groups: arithmetic, bitwise, relational, and logical.

 

Arithmetic Operators

Arithmetic operators are used in mathematical expressions in the same way that they are used in algebra. The following table lists the arithmetic operators:

 

 

The operands of the arithmetic operators must be of a numeric type. You cannot use them on boolean types, but you can use them on char types, since the char type in Java is a subset of int.

The Basic Arithmetic Operators

The basic arithmetic operations: addition, subtraction, multiplication, and division, all behave the same. The minus operator also has a unary form which negates its single operand. Remember that when the division operator is applied to an integer type, there will be no fractional component attached to the result.

 

The following simple example program demonstrates the arithmetic operators. It also illustrates the difference between floating-point division and integer division.

 

// Demonstrate the basic arithmetic operators.

class BasicMath {

public static void main(String args[]) {

// arithmetic using integers

System.out.println(“Integer Arithmetic”);

int a = 1 + 1;

int b = a * 3;

int c = b / 4;

int d = c – a;

int e = -d;

System.out.println(“a = ” + a);

System.out.println(“b = ” + b);

System.out.println(“c = ” + c);

System.out.println(“d = ” + d);

System.out.println(“e = ” + e);

// arithmetic using doubles

System.out.println(“\nFloating Point Arithmetic”);

double da = 1 + 1;

double db = da * 3;

double dc = db / 4;

double dd = dc – a;

double de = -dd;

System.out.println(“da = ” + da);

System.out.println(“db = ” + db);

System.out.println(“dc = ” + dc);

System.out.println(“dd = ” + dd);

System.out.println(“de = ” + de);

}

}

 

When you run this program, you will see the following output:

Integer Arithmetic

a = 2

b = 6

c = 1

d = -1

e = 1

Floating Point Arithmetic

da = 2.0

db = 6.0

dc = 1.5

dd = -0.5

de = 0.5

The Modulus Operator

The modulus operator, %, returns the remainder of a division operation. It can be applied to floating-point types as well as integer types. The following example program demonstrates the %:

 

// Demonstrate the % operator.

class Modulus {

public static void main(String args[]) {

int x = 42;

double y = 42.25;

System.out.println(“x mod 10 = ” + x % 10);

System.out.println(“y mod 10 = ” + y % 10);

}

}

When you run this program you will get the following output:

x mod 10 = 2

y mod 10 = 2.25

Arithmetic Assignment Operators

Java provides special operators that can be used to combine an arithmetic operation with an assignment. For example:

a = a + 4;

 

In Java, you can rewrite this statement as shown here:

a += 4;

 

This version uses the += assignment operator. Both statements perform the same action: they increase the value of a by 4. Here is another example,

a = a % 2;

 

which can be expressed as

a %= 2;

 

In this case, the %= obtains the remainder of a/2 and puts that result back into a. There are assignment operators for all of the arithmetic, binary operators. Thus, any statement of the form

var = var op expression;

 

can be rewritten as

var op= expression;

 

The assignment operators provide two benefits. First, they save you a bit of typing, because they are “shorthand” for their equivalent long forms. Second, they are implemented more efficiently by the Java run-time system than are their equivalent long forms. Here is a sample program that shows several op= operator assignments in action:

 

// Demonstrate several assignment operators.

class OpEquals {

public static void main(String args[]) {

int a = 1;

int b = 2;

int c = 3;

a += 5;

b *= 4;

c += a * b;

c %= 6;

System.out.println(“a = ” + a);

System.out.println(“b = ” + b);

System.out.println(“c = ” + c);

}

}

The output of this program is shown here:

a = 6

b = 8

c = 3

Increment and Decrement

The ++ and the – – are Java’s increment and decrement operators. The increment operator increases its operand by one. The decrement operator decreases its operand by one. For example, this statement:

x = x + 1;

 

can be rewritten like this by use of the increment operator:

x++;

 

Similarly, this statement:

x = x – 1;

 

is equivalent to

x–;

These operators are unique in that they can appear both in postfix form, where they follow the operand as just shown, and prefix form, where they precede the operand. In the foregoing examples, there is no difference between the prefix and postfix forms. In the prefix form, the operand is incremented or decremented before the value is obtained for use in the expression. In postfix form, the previous value is obtained for use in the expression, and then the operand is modified. For example:

 

x = 42;

y = ++x;

 

In this case, y is set to 43 as you would expect, because the increment occurs before x is assigned to y. Thus, the line y = ++x; is the equivalent of these two statements:

x = x + 1;

y = x;

 

However, when written like this,

x = 42;

y = x++;

 

the value of x is obtained before the increment operator is executed, so the value of y is 42. Of course, in both cases x is set to 43. Here, the line y = x++; is the equivalent of these two statements:

y = x;

x = x + 1;

 

The following program demonstrates the increment operator.

 

// Demonstrate ++.

class IncDec {

public static void main(String args[]) {

int a = 1;

int b = 2;

int c;

int d;

c = ++b;

d = a++;

c++;

System.out.println(“a = ” + a);

System.out.println(“b = ” + b);

System.out.println(“c = ” + c);

System.out.println(“d = ” + d);

}

}

The output of this program follows:

a = 2

b = 3

c = 4

d = 1

 

The Bitwise Operators

Java defines several bitwise operators which can be applied to the integer types, long, int, short, char, and byte. These operators act upon the individual bits of their operands. They are summarized in the following table:

 

 

 

Since the bitwise operators manipulate the bits within an integer, it is important to understand what effects such manipulations may have on a value. All of the integer types are represented by binary numbers of varying bit widths. For example, the byte value for 42 in binary is 00101010, where each position represents a power of two, starting with 20 at the rightmost bit. The next bit position to the left would be 21, or 2, continuing toward the left with 22, or 4, then 8, 16, 32, and so on. All of the integer types except char are signed integers. This means that they can represent negative values as well as positive ones.

The Bitwise Logical Operators

The bitwise logical operators are &, |, ^, and ~. The following table shows the outcome of each operation.

 

 

The Bitwise NOT

Also called the bitwise complement, the unary NOT operator, ~, inverts all of the bits of its operand. For example, the number 42, which has the following bit pattern:

 

00101010

becomes

11010101

after the NOT operator is applied.

 

The Bitwise AND

The AND operator, &, produces a 1 bit if both operands are also 1. A zero is produced in all other cases. Here is an example:

 

00101010         42

&00001111         15

————–

00001010         10

 

The Bitwise OR

The OR operator, |, combines bits such that if either of the bits in the operands is a 1, then the resultant bit is a 1, as shown here:

 

00101010        42

| 00001111       15

————–

00101111         47

 

The Bitwise XOR

The XOR operator, ^, combines bits such that if exactly one operand is 1, then the result is 1. Otherwise, the result is zero. The following example shows the effect of the ^. This example also demonstrates a useful attribute of the XOR operation. Notice how the bit pattern of 42 is inverted wherever the second operand has a 1 bit. Wherever the second operand has a 0 bit, the first operand is unchanged. You will find this property useful when performing some types of bit manipulations.

 

00101010        42

^00001111       15

————-

00100101         37

 

Using the Bitwise Logical Operators

The following program demonstrates the bitwise logical operators:

 

// Demonstrate the bitwise logical operators.

class BitLogic {

public static void main(String args[]) {

String binary[] = {

“0000”, “0001”, “0010”, “0011”, “0100”, “0101”, “0110”, “0111”,

“1000”, “1001”, “1010”, “1011”, “1100”, “1101”, “1110”, “1111”

};

int a = 3; // 0 + 2 + 1 or 0011 in binary

int b = 6; // 4 + 2 + 0 or 0110 in binary

int c = a | b;

int d = a & b;

int e = a ^ b;

int f = (~a & b) | (a & ~b);

int g = ~a & 0x0f;

System.out.println(” a = ” + binary[a]);

System.out.println(” b = ” + binary[b]);

System.out.println(” a|b = ” + binary[c]);

System.out.println(” a&b = ” + binary[d]);

System.out.println(” a^b = ” + binary[e]);

System.out.println(“~a&b|a&~b = ” + binary[f]);

System.out.println(” ~a = ” + binary[g]);

}

}

In this example, a and b have bit patterns which present all four possibilities for two binary digits: 0-0, 0-1, 1-0, and 1-1. You can see how the | and & operate on each bit by the results in c and d. The values assigned to e and f are the same and illustrate how the ^ works. The string array named binary holds the human-readable, binary representation of the numbers 0 through 15. In this example, the array is indexed to show the binary representation of each result. The array is constructed such that the correct string representation of a binary value n is stored in binary[n]. The value of ~a is ANDed with 0x0f (0000 1111 in binary) in order to reduce its value to less than 16, so it can be printed by use of the binary array. Here is the output from this program:

 

a = 0011

b = 0110

a|b = 0111

a&b = 0010

a^b = 0101

~a&b|a&~b = 0101

~a = 1100

 

The Left Shift

The left shift operator, <<, shifts all of the bits in a value to the left a specified number of times. It has this general form:

value << num

 

Here, num specifies the number of positions to left-shift the value in value. That is, the << moves all of the bits in the specified value to the left by the number of bit positions specified by num. For each shift left, the high-order bit is shifted out (and lost), and a zero is brought in on the right. The following program demonstrates this concept:

 

// Left shifting a byte value.

class ByteShift {

public static void main(String args[]) {

byte a = 64, b;

int i;

i = a << 2;

b = (byte) (a << 2);

System.out.println(“Original value of a: ” + a);

System.out.println(“i and b: ” + i + ” ” + b);

}

}

 

The output generated by this program is shown here:

Original value of a: 64

i and b: 256 0

 

The Right Shift

The right shift operator, >>, shifts all of the bits in a value to the right a specified number of times. Its general form is shown here:

value >> num

 

Here, num specifies the number of positions to right-shift the value in value. That is, the >> moves all of the bits in the specified value to the right the number of bit positions specified by num. The following code fragment shifts the value 32 to the right by two positions, resulting in a being set to 8:

int a = 32;

a = a >> 2; // a now contains 8

 

When a value has bits that are “shifted off,” those bits are lost. For example, the next code fragment shifts the value 35 to the right two positions, which causes the two low-order bits to be lost, resulting again in a being set to 8.

int a = 35;

a = a >> 2; // a still contains 8

 

Looking at the same operation in binary shows more clearly how this happens:

00100011 35

>> 2

00001000 8

 

Bitwise Operator Assignments

All of the binary bitwise operators have a shorthand form similar to that of the algebraic operators, which combines the assignment with the bitwise operation. For example, the following two statements, which shift the value in a right by four bits, are equivalent:

a = a >> 4;

a >>= 4;

 

Likewise, the following two statements, which result in a being assigned the bitwise expression a OR b, are equivalent:

a = a | b;

a |= b;

 

The following program creates a few integer variables and then uses the shorthand form of bitwise operator assignments to manipulate the variables:

 

class OpBitEquals {

public static void main(String args[]) {

int a = 1;

int b = 2;

int c = 3;

a |= 4;

b >>= 1;

c <<= 1;

a ^= c;

System.out.println(“a = ” + a);

System.out.println(“b = ” + b);

System.out.println(“c = ” + c);

}

}

 

The output of this program is shown here:

a = 3

b = 1

c = 6

 

Relational Operators

The relational operators determine the relationship that one operand has to the other. The relational operators are shown here:

 

 

The outcome of these operations is a boolean value. The relational operators are most frequently used in the expressions that control the if statement and the various loop statements. Any type in Java, including integers, floating-point numbers, characters, and Booleans can be compared using the equality test, ==, and the inequality test, !=. Remember: a single equal sign is the assignment operator. Only numeric types can be compared using the ordering operators. That is, only integer, floating-point, and character operands may be compared to see which is greater or less than the other. As stated, the result produced by a relational operator is a boolean value. For example, the following code fragment is perfectly valid:

int a = 4;

int b = 1;

boolean c = a < b;

In this case, the result of a<b (which is false) is stored in c.

In C/C++, true is any nonzero value and false is zero. In Java, true and false are nonnumeric values which do not relate to zero or nonzero. Therefore, to test for zero or nonzero, you must explicitly employ one or more of the relational operators.

 

Boolean Logical Operators

The Boolean logical operators shown here operate only on boolean operands. All of the binary logical operators combine two boolean values to form a resultant  boolean value.

 

 

The logical Boolean operators, &, |, and ^, operate on boolean values in the same way that they operate on the bits of an integer. The logical! Operator inverts the Boolean state: true to false and false to true. The following table shows the effect of each logical operation:

 

Here is a program that is almost the same as the BitLogic example shown earlier, but it operates on boolean logical values instead of binary bits:

 

// Demonstrate the boolean logical operators.

class BoolLogic {

public static void main(String args[]) {

boolean a = true;

boolean b = false;

boolean c = a | b;

boolean d = a & b;

boolean e = a ^ b;

boolean f = (!a & b) | (a & !b);

boolean g = !a;

System.out.println(” a = ” + a);

System.out.println(” b = ” + b);

System.out.println(” a|b = ” + c);

System.out.println(” a&b = ” + d);

System.out.println(” a^b = ” + e);

System.out.println(“!a&b|a&!b = ” + f);

System.out.println(” !a = ” + g);

}

}

 

After running this program, you will see that the same logical rules apply to boolean values as they did to bits. As you can see from the following output, the string representation of a Java boolean value is one of the literal values true or false:

a = true

b = false

a|b = true

a&b = false

a^b = true

a&b|a&!b = true

!a = false

Short-Circuit Logical Operators

These are secondary versions of the Boolean AND and OR operators, and are known as short-circuit logical operators. As you can see from the preceding table, the OR operator results in true when A is true, no matter what B is. Similarly, the AND operator results in false when A is false, no matter what B is. If you use the || and && forms, rather than the | and & forms of these operators, Java will not bother to evaluate the right-hand operand when the outcome of the expression can be determined by the left operand alone. This is very useful when the right-hand operand depends on the left one being true or false in order to function properly.

 

The Assignment Operator

The assignment operator is the single equal sign, =. It has this general form:

var = expression;

Here, the type of var must be compatible with the type of expression. The assignment operator does have one interesting attribute that you may not be familiar with: it allows you to create a chain of assignments. For example, consider this fragment:

int x, y, z;

x = y = z = 100; // set x, y, and z to 100

 

This fragment sets the variables x, y, and z to 100 using a single statement. This works because the = is an operator that yields the value of the right-hand expression. Thus, the value of z = 100 is 100, which is then assigned to y, which in turn is assigned to x. Using a “chain of assignment” is an easy way to set a group of variables to a common value.

 

The ? Operator

Java includes a special ternary (three-way) operator that can replace certain types of if-then-else statements. This operator is the ?, and it works in Java much like it does in C, C++, and C#. The ? has this general form:

expression1 ? expression2 : expression3

 

Here, expression1 can be any expression that evaluates to a boolean value. If expression1 is true, then expression2 is evaluated; otherwise, expression3 is evaluated. The result of the ? operation is that of the expression evaluated. Both expression2 and expression3 are required to return the same type, which can’t be void. Here is an example of the way that the ? is employed:

ratio = denom == 0 ? 0 : num / denom;

 

When Java evaluates this assignment expression, it first looks at the expression to the left of the question mark. If denom equals zero, then the expression between the question mark and the colon is evaluated and used as the value of the entire ? expression. If denom does not equal zero, then the expression after the colon is evaluated and used for the value of the entire ? expression. The result produced by the ? operator is then assigned to ratio.

 

Operator Precedence

Table 4-1 shows the order of precedence for Java operators, from highest to lowest. Notice that the first row shows items that you may not normally think of as operators: parentheses, square brackets, and the dot operator. Parentheses are used to alter the precedence of an operation. The square brackets provide array indexing. The dot operator is used to dereference objects.

 

 

Using Parentheses

Parentheses raise the precedence of the operations that are inside them. This is often necessary to obtain the result you desire. For example, consider the following expression:

a >> b + 3

 

This expression first adds 3 to b and then shifts a right by that result. That is, this expression can be rewritten using redundant parentheses like this:

a >> (b + 3)

 

However, if you want to first shift a right by b positions and then add 3 to that result, you will need to parenthesize the expression like this:

(a >> b) + 3

 

In addition to altering the normal precedence of an operator, parentheses can sometimes be used to help clarify the meaning of an expression.