Learning Java/Decision Structures

From Wikiversity
Jump to navigation Jump to search

Intro[edit | edit source]

Control flow blocks are basically blocks of code that control the way data flows, or else which statements are executed when. This can be useful if you only want certain areas of your code to be executed under a given condition.

There are two major types of decision structures: conditionals and loops. Code contained in a conditional block may or may not be executed; the decision is made at runtime based on a given condition. Code contained in a loop is repeated; how many times is also decided at runtime.

The boolean Primitive[edit | edit source]

Java has a specific kind of variable for determining whether something is true or false, called a boolean. A boolean type can be defined with a boolean literal (true or false), or by evaluating an expression with a boolean operator.

Boolean Operators[edit | edit source]

These can be used to check if something is true or false. Most take numeric variables (byte, short, int, long, float, or double) and evaluate to a boolean. Note that booleans are variables. Here is a list of all boolean operators:

Symbol Desc. Syntax Example
< Less than [variable] < [variable] if(i1 < i2)
> Greater than [variable] > [variable] if(i1 > i2)
!= Not equal [v] != [v] if(i1 != i2)
== Equal [v] == [v] if(i1 == i2)
<= and >= Less than or equal/Greater than or equal [v] >= or <= [v] if(i1 >= i2) (or other way)
|| Or boolean || boolean if(i1 == 5 || i1 > 8)
&& And b && b while(i1<0 && i2>5)
! Not !Boolean if(!b1)

As you can see above, and, or, and not are the only operators that work on booleans. These, essentially, create new booleans. For example, if you said:

boolean b1 = false;
boolean b2 = true;
boolean b3 = b1 || b2;
boolean b4 = b1 && b2;

In this example, b3 would be true (because one of b1 and b2 are true) and b4 would be false (because b1 and b2 are not both true).

Finally, you can do:

int i1=5;
int i2=5;
int i3=7;
int i4=3;
boolean b1 = i1 < i2;                         // i1 is not less than i2 (both are 5), so b1 is false
boolean b2 = i1 == i2 && i3 > i2;             // b2 is true because i1 is equal to i2, and i3 is greater than i2
boolean b3 = i4 < i3 && i1 > i3;              // b3 is false - i4 is less than i3, but i1 is NOT greater than i3
boolean b4 = i4 < i3 || i1 > i3;              // b4 is true because i4 < i3. Only one is needed because it is an ||
boolean b5 = (i4 < i3 && i3 < i2) || i3 > i1; // See below for info on parentheses
boolean b6 = !true;                           // This is false because !true is false, and !false is true.

Expressions within parenthesis are always evaluated first, from inside to outside. Ample use of parentheses can greatly clarify your intent. For example, consider the following code:

boolean a = true;
boolean b = true;
boolean c = false;

boolean result = a || b && c;

What value is stored in result? If the or is evaluated first, then the result is false, because the code would evalute to

a || b && c
true || true && false
true && false
false

If the and is evaluated first, though, the result is true:

a || b && c
true || true && false
true || false
true

There are rules governing which operators are evaluated first. You could remember that logical and has a higher precedence than logical or (that is, and is evaluated first), you could look it up, or you could just use parentheses! Then you don't have to bother memorizing operator precedence, or waste time checking a table.

Besides, what if you wanted the or evaluated first? You're sunk... or you could add parentheses to ensure that the or is first:

boolean result = (a || b) && c;

This will force the or to evaluate first, and be sure that anyone reading your code will know what you mean.

You will learn below how these boolean operators can be used inside control flow blocks.

If/Else[edit | edit source]

You have seen this statement used in the previous section:

if (ourShip.speed < 10) 
    ourShip.mainThrustPulse(2);

"ourShip.speed<10" is a boolean. If it is true, then it will do what comes after. Note that ourShip.speed and "10" are not booleans. The < makes a boolean if the speed is less than 10. If you did the following:

if (true) 
    ourShip.mainThrustPulse(2);

Guess what - it would automatically go to the preceding statement. Note that this can only be used for one statement. If you want to execute multiple statement for a given condition you can do:

if (CONDITION)
{//THEN...
   //DO SOMETHING
   //DO SOMETHING2
}

Everything within { and } is executed if CONDITION is true. Now, suppose you want multiple if statements. You could have separate if statements, however if the conditions are exclusive (meaning that one or the other can be true but never more than one) then you can do:

if (CONDITION)
{
   //DO SOMETHING
}
else if (SECOND CONDITION)
{
   //DO SOMETHING DIFFERENT
}
else if (ANOTHER CONDITION)
{
   //DO SOMETHING ELSE
}

To execute a block of code when the condition of the if statement is false the following code can be used:

if (CONDITION)
{
   //DO SOMETHING
}
else
{
   //DO SOMETHING ELSE;
}

Back to our ship. Lets make an if/else block that does: "If the ship's speed is less than 10, fire 2 pulses. If it is less than 15, fire one. Otherwise, lower the speed by firing backwards (-1)"

if (ourShip.speed < 10)
{
   ourShip.mainThrustPulse(2);
}
else if(ourShip.speed < 15)
{
   ourShip.mainThrustPulse(1);
}
else
{
   ourShip.mainThrustPulse(-1);//Slow down
}
Activity: if/else operators
Design an if/else block that checks if int i1 is equal to i2. If it is, print "Equal" and if not, print "Not equal". Note: Use System.out.println("TEXT HERE"); to print to command line. Also, note that to check if an int is equal to another in a boolean, use:
 if (INT1 == INT2)


Answer:

if (i1 == i2)
{
   System.out.println("Equal");
}
else
{
   System.out.println("Not equal");
}

Some examples of the usage of else/if:

public class Examples 
{
    public static void main (String[] args) 
    {
        int i1 = 7;
	
	  //1. Check if an integer is equal to 1
      
        if (i1 == 1)
        {
            System.out.println("Step 1 - Equal");
        }
        else
        {
            System.out.println("Step 1 - Not Equal");
        }
	
        //2. Check if an integer is equal to 6 then 7
      
        if (i1 == 6)
        {
            System.out.println("Step 2 - Equal #1");
        }
        else if (i1 == 7)
        {
            System.out.println("Step 2 - Equal #2");
        }
        else 
        {
            System.out.println("Step 2 - Not Equal");
        }
    }
}

If you compile this, the result should be:

Step 1 - Not Equal

Step 2 - Equal #2


Note that any code for the "Ship" cannot be executed because that class does not exist and neither does the value "speed". You can make it a class, though, when you learn about Classes and Objects.

Switch[edit | edit source]

There are times in which you wish to check for a number of conditions, and to execute different code depending on the condition. One way to do this is with if/else logic, such as the example below:

int x = 1;
int y = 2;

if (SOME_INT == x)
{
    //DO SOMETHING
}
else if (SOME_INT == y)
{
    //DO SOMETHING ELSE
}
else
{
    //DEFAULT CONDITION
}

This works, however another structure exists which allows us to do the same thing. Switch statements allow the programmer to execute certain blocks of code depending on exclusive conditions. The example below shows how a switch statement can be used:

int x = 1;
int y = 2;

switch (SOME_INT)
{
   case x:
      method1(SOME_INT);
      break;

   case y: 
      method2(SOME_INT);
      break;

   default:
      method3();
      break;
}

Switch takes a single parameter, which can be either an integer or a char. In this case the switch statement is evaluating SOME_INT, which is presumably an integer. When the switch statement is encountered SOME_INT is evaluated, and when it is equal to x or y, method1 and method2 are executed, respectively. The default case executes if SOME_INT does not equal x or y, in this case method3 is executed. You may have as many case statements as you wish within a switch statement.

Notice in the example above that "break" is listed after each case. This keyword ensures that execution of the switch statement stops immediately, rather than continuing to the next case. Were the break statement were not included "fall-through" would occur and the next case would be evaluated (and possibly executed if it meets the conditions).

While Loops[edit | edit source]

Loops will execute a block of code while a given condition is true. Basically, that block of code is executed until the condition is false. The condition is checked before the block of code is executed each time. The basic syntax:

while (CONDITION)
{
   //DO SOMETHING
}

So, you can guess that:

while (true)
{
   //DO SOMETHING
}

will execute the code within the while loop forever. The statement within the ( and ) is always a boolean condition.

Do..While Loops[edit | edit source]

A do..while loop is similar to a while loop with one major difference, which is that the condition is checked after the loop executes. This means that the block of code in the body of the do..while loop will always execute at least one time. The code below is an example of a do..while loop:

do
{
    //DO SOMETHING
} while (CONDITION);

Exercise 1: Design a while block that executes the if/else if/else code for the ship in the If/Else Statements section forever.

Exercise 2: Change the above so that it stops after 10 times. You will need to know the < operator: using the if statment, "if(SOMETHING < SOMETHING2) {...}" is valid. Basically, if s is less than s2 the next part will execute. You should use int variables for this exercise.



Answer to exercise 2:

int times=0;
while(times < 10)
{
   //Put if/else code here...
   times++; //Equivalent of times = times + 1;
}

For Loop[edit | edit source]

A for loop is a neat package for executing some statements a set number of times. The syntax is fairly simple:

for (VARIABLE INITIALIZATION; CONDITIONAL CHECK; INCREMENT/DECREMENT)
{
    //statements to be executed
}

The code below is an example of a for loop:

for (int i = 0; i < 10; i++)
{
     System.out.println(i);
}

In this example, we declare an integer named i and initialize it to 0 in the initialization step. In the conditional test, we check to see that the value of i is strictly less than 10. Finally, the increment step says i++, which is a shorthand for i=i+1, or add 1 to i. Similar to the while loop the condition is checked every time before the body of the loop is executed. Think about this code and try to determine what the output will be. Will this execute when the value of i equals 10? The output is shown below:

0
1
2
3
4
5
6
7
8
9

Notice that "10" is not included in the output. This is because the conditional check is i < 10. When i equals 10 the condition is no longer true, and the loop will not execute.

Foreach Loops[edit | edit source]

There is another for known as a foreach loop which has been more recently introduced to Java made for iteration over a collection. It uses any type of list structure as its base, including arrays and certain types of Collections. Collections are data structures with certain properties that make manipulating large amounts of data easy. In the example below we use an ArrayList which is similar to a normal array, except that it can grow dynamically and it has a number of methods (such as add(), remove(), get(), etc) to make it easier to work with than a normal array. See the example below:

int[] integerArray = {2,3,4,5}; // an integer array is a basic list of integers
ArrayList<Integer> listOfNumbers = new ArrayList<Integer>(); //Don't worry about this syntax now

for (int i : integerArray)
{
     i = i+1;
     listOfNumbers.add(i);
}
//integerArray now equals [2,3,4,5]
//listOfNumbers now equals [3,4,5,6]

In this example we are iterating an array of integers named integerArray. The for loop will run 4 times, each time with "i" equaling a different value in the array. When the items in the list structure (see the example above) are primitive values (byte, int, long, float, double, boolean, char...) the value of "i" will just be a copy. This is why the values inside of integerArray are not changed even though "i" is changed inside the loop.

If, however, the values in the list are references, they will be directly under the influence of any changes occurring inside the loop as in this example:

//Note, this code will not compile with a working Ship class
ArrayList<Ship> listOfShips = new ArrayList<Ship>(); //Don't worry about this syntax now
listOfShips.add(new Ship(Color.RED));
listOfShips.add(new Ship(Color.BLUE));
listOfShips.add(new Ship(Color.GREEN));

ArrayList<Ship> newListOfShips = new ArrayList<Ship>(); //Don't worry about this syntax now

for (Ship shipToChange : listOfShips)
{
     shipToChange.setColor(Color.BLACK);
     newListOfShips.add(shipToChange);
}
//all ships in listOfShips now have color black
//all ships in newListOfShips now have color black

In this example we start out with a list named listOfShips holding three "ships" all of different colors. The for loop iterated through the list and changed each ships's color to black, then it added the ship to another list called newListOfShips. Since shipToChange is a reference to a variable instead of a variable itself, changes to it affect the items in listOfShips.



Project: Java
Previous: Basic Java Language — Learning Java/Decision Structures — Next: Java Objects and Classes