Monday, November 3, 2008

More of The Operators

Relational Operators

The relational operators determine the relationship that one operand has to the other. Specifically, they determine equality and ordering. The relational operators are shown here:

 

Operator       Result

==                    Equal to

!=                     Not equal to

>                      Greater than

<                      Less than

>=                    Greater than or equal to

<=                    Less than or equal to

 

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, !=. Notice that in Java (as in C/C++/C#) equality is denoted with two equal signs, not one. (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.

If you are coming from a C/C++ background, please note the following.  In C/C++, these types of statements are very common:

 

int done;

// ...

if(!done) ... // Valid in C/C++

if(done) ... // but not in Java.

In Java, these statements must be written like this:

if(done == 0)) ... // This is Java-style.

if(done != 0) ...

 

The reason is that Java does not define true and false in the same way as C/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.

 

Operator         Result

&                     Logical AND

|                       Logical OR

^                      Logical XOR (exclusive OR)

||                       Short-circuit OR

&&                   Short-circuit AND

!                       Logical unary NOT

&=                   AND assignment

|=                     OR assignment

^=                    XOR assignment

==                    Equal to

!=                     Not equal to

?:                     Ternary if-then-else

 

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 == false and !false == 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:

THE

JAVA

LANGUAGE

// 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

Java provides two interesting Boolean operators not found in many other computer languages. 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.

 

For example, the following code fragment shows how you can take advantage of short-circuit logical evaluation to be sure that a division operation will be valid before evaluating it:

 

if (denom != 0 && num / denom > 10)

 

Since the short-circuit form of AND (&&) is used, there is no risk of causing a run-time exception when denom is zero. If this line of code were written using the single & version of AND, both sides would have to be evaluated, causing a run-time exception when denom is zero.

 

It is standard practice to use the short-circuit forms of AND and OR in cases

involving Boolean logic, leaving the single-character versions exclusively for bitwise operations. However, there are exceptions to this rule. For example, consider the following statement:

 

if(c==1 & e++ < 100) d = 100;

 

Here, using a single & ensures that the increment operation will be applied to e whether c is equal to 1 or not.

 

The Assignment Operator

You have been using the assignment operator since Chapter 2. Now it is time to take a formal look at it. The assignment operator is the single equal sign, =. The assignment operator works in Java much as it does in any other computer language.

 

It has thisgeneral 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:

ANGUAGE

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#. It can seem somewhat confusing at first, but the ? can be used very effectively once mastered.

 

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.

 

Here is a program that demonstrates the ? operator. It uses it to obtain the absolute value of a variable.

 

// Demonstrate ?.

class Ternary {

public static void main(String args[]) {

96  

int i, k;

i = 10;

k = i < 0 ? -i : i; // get absolute value of i

System.out.print("Absolute value of ");

System.out.println(i + " is " + k);

i = -10;

k = i < 0 ? -i : i; // get absolute value of i

System.out.print("Absolute value of ");

System.out.println(i + " is " + k);

}

}

 

The output generated by the program is shown here:

Absolute value of 10 is 10

Absolute value of -10 is 10

 

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. As you know from the previous chapter, the square brackets provide array indexing. The dot operator is used to dereference objects and will be discussed later in this book.

 

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

ANGUAGE

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. For anyone reading your code, a complicated expression can be difficult to understand. Adding redundant but clarifying parentheses to complex expressions can help prevent confusion later.

 

For example, which of the following expressions is easier to read?

 

a | 4 + c >> b & 7

(a | (((4 + c) >> b) & 7))

 

One other point: parentheses (redundant or not) do not degrade the performance of your program. Therefore, adding parentheses to reduce ambiguity does not negatively affect your program.

No comments: