Site Search

# Chapter 4: Decision Structures

Learning Objectives

After completion of this chapter, you should be able to

## Explain the concept of flow of control

Unless indicated otherwise, the order of statement execution (the flow of control) through a method is linear. That is, one statement after the other in the order they are written

Java provides two other ways to change the flow of control:

1. Conditional statements (branching: `if` and `switch`)
2. Repetition statements (looping: `while`, `for`, and `do`)

## Use conditional statements to change the flow of control

A conditional statement lets us select which statement will be executed next. By allowing selections, conditional statements give us the power to make basic decision choices in our programs

Java's conditional statements include

1. `if` statement
2. `if-else` statement
3. `if-else-if` statement
4. `switch` statement
5. conditional operator `?:`

### Use `if` statements

The `if` statement has the following syntax:

if (condition)
{
statement(s);
}

The semantics (meaning) of the `if` statement is if the condition is true, do the block of statement(s) that immediately follow.

If the condition is false (not true), skip the block of statement(s) that immediately follow.

An example of an `if` statement:

if ( age >= 21 )
{
System.out.println("Congratulations, you're legal");
}
// Declare cut-off age
final int YOUTH = 21;

// Declare variables for user input
int age;

// Create a Scanner object to read input
Scanner keyboard = new Scanner(System.in);

// Get the user's age
age = keyboard.nextInt();

// Example if statement
if ( age < YOUTH )
{
System.out.println ("Youth is a wonderful thing.");
}

// Always do this statement
System.out.println ("Age is a state of mind.");

### Write Boolean expressions using relational operators

A condition often uses one of Java's six relational operators, which all return Boolean results:

1. `==` equal to
2. `!=` not equal to
3. `<` less than
4. `>` greater than
5. `<=` less than or equal to
6. `>=` greater than or equal to

Note the difference between the equality operator (`==`) and the assignment operator (`=`)

The following expression is an example of a Boolean expression that uses relational operators.

(age >= YOUTH)

### Use `if-else` Statement

An `else` clause can be added to an `if` statement to make it an `if-else` statement:

if ( condition )
{
statement(s);
}
else
{
statement(s);
}

The semantics (meaning) of the `if-else` statement is that if the condition is `true`, the first block of statements are executed; otherwise, if the condition is `false`, then block of statements after the else are executed.

One or the other block of statements will be executed, but not both

// Declare constant values
final double PAY_RATE = 8.25;
final int HOURS_IN_WORK_WEEK = 40;

// Declare variables
int hours;
double pay;

// Create a Scanner object to read input
Scanner keyboard = new Scanner(System.in);

// Get the number of hours worked this week
System.out.print ("Enter the number of hours worked: ");
hours = keyboard.nextInt();

// Use if-else statement to determine pay
// overtime is at "time and a half"
if ( hours > HOURS_IN_WORK_WEEK )
{
pay = (HOURS_IN_WORK_WEEK * PAY_RATE) +
((hours - HOURS_IN_WORK_WEEK) * (PAY_RATE * 1.5));
}
else
{
pay = hours * PAY_RATE;
}

// Display the amount earned
System.out.println ("Gross earnings: \$" + pay);

## Use nested`if` Statements

An if statement can be nested inside another if statement.

if (num1 < num2)
{
if (num1 < num3)
min = num1;
else
min = num3;
}
else
{
if (num2 < num3)
min = num2;
else
min = num3;
}
System.out.println(min);

## Use the String class to compare strings

A string in Java is an object. We should not use the relational operators to compare strings.

The `equals` and `equalsIgnoreCase` methods can be used to compare two strings with each other. Do not use `==` operator for comparing strings for equality.

String userInput;
userInput = keyboard.nextLine();

if (userInput.equals("hello"))
{
System.out.println ("Hello to you too");
{
else if (userInput.equalsIgnoreCase("goodbye"))
{
System.out.println("See you later");
}

### Use the String class `compareTo` method

The `compareTo` method of the String class returns a int value `-1`, `0`, or `1` when comparing two strings

// Compare name1 with name2
if (name1.compareTo(name2) < 0)
{
System.out.println(name1 + " is less than " + name2);
}
else if (name1.compareTo(name2) == 0)
{
System.out.println(name1 + " is equal to " + name2);
}
else if (name1.compareTo(name2) > 0)
{
System.out.println(name1 + " is greater than " + name2);
}

## Explain floating point approximation and representation errors

When dealing with double values and floating point arithmetic, Java programs, some slight approximation and representational errors may occur.

For example, the floating point division 1.0 / 3.0 results in 0.3333333333333333 instead of a true 1/3.

We need to take care when comparing floating point values as the representational errors may produce incorrect comparisons. For example, consider the numbers:

```    `1.0000000000000001` and `0.9999999999999999`
```

Are the equal? Is one greater than the other?

In Java, they would be considered not equal, but, in many cases, we may consider them as equal, assuming a margin of error.

For flexibility, it is wise to use a named constant to represent the allowable margin of error and compare values within the margin of error

private final double MARGIN_OF_ERROR = 0.000001;

We can now use this named constant to test whether two `double` values are equal, within the margin of error.

double difference = number1 - number2;
if (Math.abs(difference) <= MARGIN_OF_ERROR)
{
// two numbers are equal, plus or minus the margin of error
}

## Use the `DecimalFormat` class to format floating point numbers

When printing out double and float values, the full fractional value will be printed. The `DecimalFormat` class can be used to format these values.

In order to use the DecimalFormat class, the Java import statement must be used. At the top of the program, include the statement:

```   import java.text.DecimalFormat;
```

`DecimalFormat` Class Example

import java.text.DecimalFormat; // Needed for DecimalFormat

public class Format1
{
public static void main(String[] args)
{
double number1 = 0.166666666666667;
double number2 = 1.666666666666667;

// Create a DecimalFormat object.
DecimalFormat formatter = new DecimalFormat("#0.00");

// Format and display the variables.
System.out.println(formatter.format(number1));
System.out.println(formatter.format(number2));
}
}

Produces the following output:

```   0.17
1.67
```

The code:

double number = 1234567.899;
DecimalFormat formatter = new DecimalFormat("#,##0.00");
System.out.println(formatter.format(number));

Produces the following output:

```   1,234,567.90
```

The code:

double number1 = 0.12;
DecimalFormat formatter = new DecimalFormat("#0%");
System.out.println(formatter.format(number1));

Produces the following output:

```   12%
```

## Use logical operators with Boolean expressions

Boolean expressions can also use the following three logical operators:

1. `!` not
2. `&&` and
3. `||` or

All three take Boolean operands and produce a Boolean result.

`!` is a unary operator, it has one operand. `&&` and `||` are binary operators, they each have two operands.

The not `!` expression is true if a is false and is false is a is true

```      (`!`a)
```

The and `&&` expression is true if both a and b are true, and false otherwise

```      (a `&&` b)
```

The or `||` expression is true if a or b or both are true, and false otherwise

```      (a `||` b)
```

### Use logical operators in conditional expressions

Conditions in `if` statements and loops can use logical operators to form complex expressions

if ((total < MAX) && (count <= 10))
{
System.out.println ("Processing ...");
}

Logical operators have precedence relationships between themselves and other operators

1. `!` has highest precedence
2. `&&` is next
3. `||` is lowest in precedence

## Use cascading`if` statements

Many programs need to test a series of conditions, one after the other, until finding one that's true.

This situation is best handled by nesting a series of `if` statements in such a way that the `else` clause of each is another `if` statement. This is called a cascading `if` statements.

if (score >= 90)
{
System.out.println("A");
}
else if ((score >= 80) && (score <= 89))
{
System.out.println("B");
}
else if ((score >= 70) && (score <= 79))
{
System.out.println("C");
}
else if ((score >= 60) && (score <= 69))
{
System.out.println("D");
}
else
{
System.out.println("F");
}

## Use `Boolean` variables

`Boolean` is a built-in primitive type in Java. We can declare and use variables of type Boolean in the same manner as variables of type `int` or `double`.

// Declare a Boolean variable
boolean isValid;

// Set its value to true or false
isValid = ((number == 5) || (number == 7) || (number >= 11));

// Display the value stored in isValid
System.out.println("isValid is " + isValid);

## Write boolean methods

Methods may be written to return a Boolean result type.

For example, with our Fraction class we may want a method that returns true if the numerator and denominator are the same value, false otherwise

public boolean isEqualToOne()
{
if (getNumerator() == getDenominator())
{
return true;
}
else
{
return false;
}
}

## Use the `switch` statement

The `switch` statement provides a way to choose from a list of possible actions.

switch ( expression )
{
case value1 :
statement(s) when expression == value1;
break;
case value2 :
statement(s) when expression == value2;
break;
case value3 :
statement(s) when expression == value3;
break;
default :
statement(s) if no previous match;
}

A `break` statement is used as the last statement in each case's statement list.

The `break` statement causes the switch statement to end and control to transfer to the end of the `switch` statement. The program continues executing with the statement that follows the switch statement.

A `switch` statement can have an optional `default` case.

Example switch statement

int score = 8;
switch (score)
{
case 10 :
System.out.println ("Excellent.");
break;
case 9 :
System.out.println ("well above average.");
break;
case 8:
System.out.println ("above average.");
break;
case 7 :
case 6 :
System.out.print ("Average. You should seek ");
System.out.println ("out help.");
break;
default :
System.out.println ("not passing.");
}

if two or more case labels result in the same action, they can be combined. In the previous example, cases 7 and 6 are combined.

The `switch` statement has two primary advantages over the cascaded `if` statement.

• Using `switch` statements instead of cascaded if statements can make a program easier to understand.
• The `switch` statement is often faster than a cascaded if statement. As the number of cases increases, the speed advantage of the switch becomes more significant.

### Recognize the limitations of the switch statement

The `switch` statement can not replace every cascaded `if` statement.

To qualify for conversion to a `switch`, every test in a cascaded if must compare the same variable (or expression) for equality (`==`) with a constant:

```   `if` (x `==` constant-expression1)
statement1;
`else if` (x `==` constant-expression2)
statement2;
`else if` (x `==` constant-expression3)
statement3;
```

A switch statement's controlling expression must have type `char`, `byte`, `short`, or `int`.

## Use the conditional operator

The conditional operator is a ternary (three operand) operator.

The conditional operator allows a programmer to write a simple `if-else` type statement.

The format of the operators is:

```      expression1 `?` expression2 `:` expression3;
```

The conditional operator can also return a value.

Example of Conditional Operator

The conditional operator can be used as a shortened `if-else` statement:

x > y ? z = 10 : z = 5;

This line is functionally equivalent to:

if (x > y)
z = 10;
else
z = 5;

## Use the `Random` class

The Random class may be used to generate a random number

import java.util.Random;

public class RandomTester
{
public static void main(String[] args)
{
// local variables
int number1;
double number2;

// Create a Random object
Random randomNumbers = new Random();

// Get a random number between 0 and 100
number1 = randomNumbers.nextInt(100);

// Get a random number between 0.0 and 1.0
number2 = randomNumbers.nextDouble();
}
}