Using Operators and Decision Constructs

Operators

Now that we know about variables we will want to increment them, add them, shift there bits and compare one to another. There are a number of operators in Java that are very similar to other programming languages.

Just as a recap about numeric promotion

Java Operators and Assignment
Assignment Associates or assigns a value to a variable, if its a primitive data type the variable will be a storage holder, if the variable is a string it will be a reference to the String object.
Comparison You have four comparison operators that can be used to compare any combination of integers, floating-point numbers, characters, they will always result in true or false
instanceof is used for object reference variables only and you can use it to check whether an object is of a particular type (class or interface)
Equality compare two things and return a boolean value (true or false)
Arithmetic standard arithmetic operators, addition (+), subtraction (-), multiplication (*), division (/) and remainder (%)
String Concatenation The plus sign can also be used to concatenate two Strings together
Increment and Decrement

These two operators (++ and --) will increment or decrement a variable by exactly one. The operator can be placed either before (prefix) or after (postfix) a variable.

Shift The shift operator shifts bits to either the right or left
Bitwise The bitwise operators take two individual bit numbers then use AND/OR to determine the result on a bit-by-bit basis. There are three bitwise operators AND (&), inclusive OR (|) and exclusive OR (^).
Bitwise Complement bitwise complement operator (~) flips the bits of the variable 1 becomes 0 and 0 becomes 1
Conditional (Ternary) is a ternary operator (?:) is a bit like a if-else statement
Primitive Casting Allows you to convert primitive values from one type to another, casting can be either explicit or implicit.
Logical The two other logical operators are the OR (||) and AND (&&) otherwise known as the "short-circuit" operators, the others being the bitwise AND and OR other wise know as "not short-circuit". When using the not short circuit (& or |) beware that it will evaluate both expressions even if the second expression would not change the outcome they are inefficient compared with the short-circuit versions.
Lambda Operator This operator divides the the lambda expression into two parts, the left side specifies the parameters required by the expression, which can be empy if no parameters are required, the right side is the lambda body which specifies the actions of the lambda expression.  
Java Operators and Assignment Examples
Assignment

int x = 7;                         // pretty standard assignment

byte b = 127;
byte c = b;                        // copy variable b into c, remember there is no relationship between b and c

String text = "Hello World!\n";    // create variable with an object type of String
String text2 = text;               // assign an object to a object variable, point to same object

float f = (float) 32.3;            // Explicitly cast the double literal to a float, otherwise compiler error

Note: if the value is too large for the data type the compiler will let you know

Comparison

if ( age > 65 ) { ... }           // greater than operator
if ( age < 65 ) { ... }           // less than operator
if ( age >= 65 ) { ... }          // greater than or equal to operator
if ( age <= 65 ) { ... }          // less than or equal to operator

Note: comparison operators always result in a boolean (true or false)

instanceof

String s = "Hello World!"
if ( s instanceof String ) { ... }

Note: it will check the superclasses as well to confirm it has a IS-A relationship

Equality

int age = 60;
if ( age == 60 ) { ... }          // compare variable age with integer 60
if ( age != 60 ) { ... }

String s1 = "Test";
String s2 = "Test";
if ( s1 == s2 ) { ... }           // compare two String objects

Arithmetic
int x = 5 * 5;
int y = 20 - 10;
int z = 20 % 3;     // this would result in 2 (20 / 3 = 6 reminder 2), you can also use this with doubles and floats

x += 5;         // this is a short hand way of saying x = x + 5;
x *= 5;         // this is a short hand way of saying x = x * 5;

Note: dividing by zero using int will throw an exception but if using doubles or floats you will get a NaN
String Concatenation

String s1 = "Hello ";
String s2 = "World!\n";
String result = s1 + s2;          // result would contain "Hello World!\n"

int a = 2;
int b = 3;
System.out.println( a + b );               // results in 5 being printed
System.out.println( "Answer: " + a + b);   // results in "Answer = 23" being printed

Note: when using integers and Strings, as long as one operand is a String the result is a String, if both operands are integers then the arithmetic will take place

Increment and Decrement int a = 4;
int b = 4;
int a_prefix = a++;        // results in variable a_prefix having the value of 4; (increment after assignment)
int b_postfix = ++b;       // results in variable b_postfix having the value of 5; (increment before assignment)
Shift int result = 95 >> 1;      // shift the bits to the right by one
int result = 95 << 2;      // shift the bits to the left by two
int result = 95 >>> 1;     // shift the bits to the right by 1 (fill the left most bits with zero's)
Bitwise

int a = 10, b = 9;
int c = a & b;             // results in 8 being assigned to c (1010 & 1001 = 1000)
int c = a | b;             // results in 11 being assigned to c (1010 | 1001 = 1011)

X Y &  (AND) |  (OR) ^  (XOR)
0 0 0 0 0
0 1 0 1 1
1 0 0 1 1
1 1 1 1 0
Bitwise Complement

int x = 5;
int y = ~x;
System.out.println("Y: " + y);     // results in "Y: -6"

~0000 0000 0000 0000 0000 0000 0000 0101 becomes 1111 1111 1111 1111 1111 1111 1111 1010

Conditional (tenary) String status = (numOfPets < 3) ? "It's OK to have a couple of pets" : "Way too many";
Primitive Casting

int a = 100;
long b = a;            // Implicit cast, an int value always fits in a long

float a = 100.001f;
int b = (int) b;       // Explicit cast, a float can loose info as an int

Note: with explicit casting you let the compiler know that you know that you may loose info

Logical

# Short-Circuit
if (( age >= 5 ) && ( age <= 17 )) { ... }       // both expressions have to be true to execute the if body
if (( age == 18 ) || ( age == 19 )) { ... }      // only one expression has to be true to execute the if body

# Not Short Circuit
if (( age >= 5 ) & ( age <= 17 )) { ... }        // both expressions have to be true to execute the if body
if (( age == 18 ) | ( age == 19 )) { ... }       // only one expression has to be true to execute the if body

Note: using the not short circuit (& or |) is inefficient because it will evaluate both expressions even if the second expression would not change the outcome.

All operators have a order of precedence, they can also operate from left-to-right or from right-to-left.

Operator Type
Associativity
() parentheses
left to right
[ ] array subscript
"
. member selection
"
++ unary postincrement
right to left
-- unary postdecrement
"
++ unary preincrement
"
-- unary predecrement
"
+ unary plus
"
- unary minus
"
! unary logical negation
"
~ unary bitwise complement
"
( type ) unary cast
"
* multiplication
left to right
/ division
"
% modulus (reminder)
"
+ addition
"
- substraction
"
<< bitwise left shift
"
>> bitwise right shift with sign extension
"
>>> bitwise right shift with zero extension
"
< relational less than
"
<= relational less than or equal to
"
> relational greater than
"
>= relational greater than or equal to
"
instanceof type comparison
"
== relational is equal to
"
!= relational is not equal to
"
& bitwise AND
"
^ bitwise exclusive OR, boolean logical exclusive OR
"
| bitwise inclusive OR, boolean logical inclusive OR
"
&& logical AND
"
|| logical OR
"
?: ternary conditional
right to left
= assignment
"
+= additional assignment
"
-= substraction assignment
"
*= multiplication assignment
"
/= division assignment
"
%= modulus assignment
"
&= bitwise AND assignment
"
^= bitwise exclusive OR assignment
"
|= bitwise inclusive OR assignment
"
<<= bitwise left shift assignment
"
>>= bitwise right shift with sign extension assignment
"
>>>= bitwise right shift with zero extension assignment
"

Control Statements and Loops

Flow control is a key part of most programming languages and Java offers several ways to do it, this web page will cover the following topics

The page is not a complete tutorial on how to use the control statements but quick look up on the syntax of the command, please refer to the Java documentation if you want a complete tutorial of the below commands.

IF statement
if (booleanExpression ) { System.out.println("Inside a IF statement ");
        
if ( age == 65 ) { System.out.println("Book yourself a retirement holiday");

if (true)
System.out.println("Hello ");       
System.out.print("World!");             // you actually don't need brackets but it can be hard to read code

if (false);                        
System.out.println("Hello World!");     // notice the semi-colon at the end of the if statement, this terminates the if statement imediately and this line always executes
IF-ELSE statement

if ( price < 100 ) {
   System.out.println("Buy it, it's a bargain");
}
else {
   System.out.println("It's to pricey wait until the sales");
}

// You can also remove the brackets when you only have one line of code for each true or false
if ( price < 100 )
   System.out.println("Buy it, it's a bargain");
else
   System.out.println("It's to pricey wait until the sales");

// Using a if-else-if
if ( price < 100 )
   System.out.println("Buy it, it's a bargin"):
else if ( price < 110 )
   System.out.println("You might be tempted");
else
   System.out.println("It's to pricey wait until the sales");

Note: always indent conditional code it makes it much more pleasant on the eyes

Ternary operator

result = ( a < b ; a ? b);

if the condition a < b is true then the value of a is assigned to result
if the condition a < b is false then the value of b is assigned to result

Note: The ternary operator (conditional operator) is a short-hand of a if-else statement

SWITCH statement

int x = 3;

switch (x) {
  case 1:
    System.out.println("x is equal to one");
    break;
  case 2:
    System.out.println("x is equal to two");
    break;
  case (1 + 2):                                   // can even use expressions as well
    System.out.println("x is equal to three");
    break;
  default:                                        // default block does not need to be at the end or even included
    System.out.println("No idea what x is ?????");
}

Note: switch statements can only evaluate byte (Byte), short (Short), int (Integer) and char (Character), enumerated types and the String class

Note: missing break statements means that all case statements will be executed, known as fall-through 
WHILE statement

int x = 0;

while ( x < 10 ) {
   System.out.println("x is still less than 10");
   x++;
}

Note: it is possible that the while body may never be executed

DO-WHILE statement

int x = 0;

do {
  System.out.println("x is still less than 10");
  x++;
} while ( x < 10 );            // notice the semi-colon 

Note: The while body will always be executed once, also notice the semi-colon at the end of the while expression 
FOR loop

for ( int x = 0; x < 10; x++) {
    System.out.println("x is still less than 10");
}

# More complex FOR loop
for ( int x = 0, y = 0; ( (x < 10) && (y < 10) ); x++, y++) {
    System.out.println("x and y are still less than 10");
}

Note: you can have only one logical expression but it can be very complex.

The for statement is made up of three parts

  • Control variable initialization (only called once)
  • Loop continuation Condition (must evaluate to true or false)
  • Increment/Decrement of the control variable (executed after the iteration)

   for ( control variable initialization ; loop continuation ; increment/decrement of the control variable )

More information about loops:

  • You cannot reference a label with the continue or break statements that are not in the loop scope, a compile error occurs
  • An outer loop cannot reference the inners loop's labels, but an inner loop can reference the outer's loop lables
  • You can break out of a nested loop from a nested loop
  • You can also completely break out of a parent loop

FOR Loop (enhanced)
init i = 0;
        
for(Strings arg : args) {
  System.out.println("Argument " + (++i) + " = " + arg);
}
BREAK statement

int counter = 1;

while (counter <= 10 ) {
   System.out.println ( "Counter = " + counter + " We will break on 5" );
   if ( counter == 5 )
      // Break out of the while loop
      break;
   counter++;
}

Note: The break statement when executed in a while, do/while or switch statement causes immediate exit from that structure and continues on to the next statement after the while, do/while or switch structure.

CONTINUE statement

int counter = 1;

while (counter <= 10 ) {

   if ( (counter % 2) == 0 ) {
      System.out.println ( "Counter = " + counter + " Do not print odd numbers" );
      counter++;
      continue;
   }
   counter++;
}

Note:The continue statement when executed in a while, do/while or switch skips the remaining body statements and proceeds to the next iteration of the loop.

LABELED statement

stop: // labeled compound statement
   for ( int row = 1; row <= 10; row++ ) {
      for ( int column = 1; column <= 5; column++ ) {
         if ( row == 5 )
            break stop;   // Jump to end of stop block
      }
   }

Note: Labeled break/continue statements are to breakout of nested set of structures, the beginning of the nested structure starts with a label which is a place that the break statement will exit from.