Controlling the Flow of Your Program - Beginning Java Programming: The Object-Oriented Approach (Programmer to Programmer) (2015)

Beginning Java Programming: The Object-Oriented Approach (Programmer to Programmer) (2015)

5. Controlling the Flow of Your Program

WHAT YOU WILL LEARN IN THIS CHAPTER:

· How to determine if a certain condition is met

· How to control what a Java program does and when it should do it

· How to use loops in Java to repeat an action

· How to determine which control structure to use

WROX.COM CODE DOWNLOADS FOR THIS CHAPTER

The wrox.com code downloads for this chapter are found at www.wrox.com/go/beginningjavaprogramming on the Download Code tab. The code is in the Chapter 5 download and individually named according to the names throughout the chapter.

Control structures allow a programmer to define how and when certain statements will be executed. In other words, if certain conditions are met, specified behaviors will result. Several structures exist in Java and other languages, such as loops and if-then statements, which allow this control to be implemented. This chapter begins by introducing (or re-introducing) some operators that will be used extensively in control structures. The operators, essentially, allow you to compare values. In order to make similar comparisons on different data types, some comparative methods will also be introduced. Once you can make these comparisons and assessments, you can start using them to make decisions. That is where the if-then statement comes in. In its simplest form, this structure can be read as follows: if some condition is true, then do something. Next, you will look at for and while loops, and some extensions of these, which allow sections of code to be repeated based on the conditions you define. A switch is an alternative structure that’s similar to an if-then statement, but offers a list of cases that can be defined so each is handled differently or so groups of cases can be handled the same. Finally, you’ll learn about some keywords that have specific uses in guiding the execution of a program.

COMPARISONS USING OPERATORS AND METHODS

You have already seen operators, such as arithmetic operators, in Chapter 2. Operators are based on mathematical concepts and many will look familiar, even to those unfamiliar with programming. This chapter discusses two types of control operators, comparativeand logical, that are used frequently in control structures. The syntax for operators will differ whether the data type is primitive or composite. Recall that primitive types include char, boolean, and many numeric representations, like int, double, and float. Arrays, strings, and other defined classes are composite data types.

Comparing Primitive Data Types with Comparison Operators

Given the importance of operators when defining control structures, this section briefly revisits some of the underlying concepts covered in Chapter 2.

For primitive data types, there are well-defined operators, as outlined in Table 5.1, which can be used to compare the values of two variables. Equality and relational comparison operators compare the values of two operands for equality, inequality, greater than, or less than. The result of these expressions is a Boolean true or false. With primitive types, the following expressions are used for comparison:

· Equal: ==

· Not equal: !=

· Greater than: >

· Greater than or equal: >=

· Less than: <

· Less than or equal: <=

Table 5.1 Control Operators for Primitive Data Types

OPERATOR

JAVA SYNTAX

ENGLISH EQUIVALENT

Equality

x == y x != y

Is x equal to y?
Is x not equal to y?

Relational

x < y x <= y x > y x >= y

Is x less than y?
Is x less than or equal to y?
Is x greater than y?
Is x greater than or equal to y?

Logical

x && y x || y !x

Are x and y both true?
Is x, y, or both true?
Is x false?

Note that the ! indicates negation. While these operators are used for most primitive data types, there is an exception; Boolean operands can only be compared with equality operators and not with relational operators. That is, true cannot be greater than or less thanfalse; however, true can be equal to true. Other primitive data types can be compared with both equality and relational operators.

It is important to distinguish a single equal sign (=) from a double equal sign (==). The first is used for variable assignment. The variable on the left is assigned the value on the right. For example, balance = 5000; assigns the value of 5000 to the variablebalance. The second is a comparison operator to test whether two things are equal. For example, balance == 5000; will return true if the value of the variable balance is 5000 and false otherwise.

Logical operators, on the other hand, are specific to Booleans, and are used to combine or negate one or more conditions. There are three logical operators: AND (&&), OR (||), and NOT (!). If two or more Boolean operands are joined using the AND operator, all must evaluate to true for the overall expression to evaluate to true. If they are joined using the OR operator, at least one of them must evaluate to true in order for the overall expression to evaluate to true. Finally, if the NOT operator precedes a Boolean operand that evaluates to true, the overall expression will evaluate to false and vice versa. It evaluates as the opposite of the original expression.

Truth tables are used in logic to show the outcome of Boolean operators on pairs of statements. In the first two columns are two statements that can be true or false. In the columns that follow, operators are listed with their results based on whether the statements are true or false. Table 5.2 is a truth table demonstrating the Boolean operators discussed here—namely NOT, AND, and OR.

Table 5.2 Boolean Operator Truth Table

P

Q

!P
NOT P

P && Q
P AND Q

P || Q
P OR Q

TRUE

TRUE

! TRUE =FALSE

True AND True = TRUE

True OR True = TRUE

TRUE

FALSE

True AND False = FALSE

True OR False = TRUE

FALSE

TRUE

! FALSE =TRUE

False AND True = FALSE

False OR True = TRUE

FALSE

FALSE

False AND False = FALSE

False OR False = FALSE

In fact, you probably encounter these kinds of logical operators in your everyday life. For example, a public transit system might follow a certain schedule if the day is Saturday OR a holiday and another schedule otherwise. In other words, if (day == Saturday || day == holiday), then follow the weekend schedule. Then it is understood that if it is Saturday or a public holiday or both, the entire statement is true. On the other hand, you might have a rule that states if a person is over 60 years old AND they possess a bus card, then their fare is reduced, or if (age > 60 && busCard == true), then charge a reduced bus fare. Then you require both conditions—a person must be over 60 AND they must have a bus card—for the entire statement to be true. Regardless of whether a person is 50 years old with a bus card or if they are 62 years old without a bus card, their fare will not be reduced.

& AND | VERSUS && AND


This section covered && and ║, the AND and OR operators. There are also bitwise operators called & and |, which behave similarly on Boolean operands. The main difference is that the double symbols && and ║ will first check the left side operand and will only check the right side if necessary. So for &&, if the left side is true, it will check if the right side is also true. If the left side is false, then you already know the outcome will be false and the right side will not be evaluated. This is called short circuiting, because like electricity will take the shortest path (sometimes causing a short circuit if there is another shorter route), these operators will stop the evaluation early if the answer is already known. This is particularly useful in avoiding exceptions or errors, when the first operator must be true in order to evaluate the second operator. A common example is (x != 0 && 1/x > 1). If you use & here, and x equals 0, then 1/x will be evaluated, but of course, zero cannot be a divisor so this would cause an error. Java’s inclusion of the && operator with short circuiting will prevent this kind of error.

Similarly, for ║, if the left side is true, there is no need to check if the right side is true, so the result will be true without evaluating the right operand. If, however, the left operand is false, it will check the right operand. You could use a very similar example (x == 0 ║ 1/x < 1) to see how the short circuiting can prevent the same errors when using the OR operand.

Comparing Composite Data Types with Comparison Methods

When you think of the differences between primitive data types, like int, and composite date types, like String, it should not be surprising that you will need to compare them in different ways. If asked the question, “Is 5 less than 10?” almost everyone will compare the two numbers in the same way and respond affirmatively. Although the comparison of char variables is not as immediately apparent, all possible char values have been assigned a numeric value, allowing them to be ordered similarly to integers. However, the question, “Is order less than delivery?” is not at all apparent. Therefore, comparison methods for composite data types must be defined in the class, rather than using the comparison operators discussed in the previous section.

This early chapter, in addition to the primitive types, includes a discussion on strings and arrays, since you will encounter both these composite data types frequently. Many more classes will be covered in later chapters. These classes are well-defined and include comparison methods. It often makes sense to compare strings relationally, such as putting a list into alphabetical order. For other composite data types, including pre-existing classes and classes you will create on your own, comparison methods can be implemented in different ways. You will read about some of these possibilities later in the book.

The String class includes an equality comparison method in the equals() method. This method will return true for any two strings with a matching sequence of characters and false if there is any difference in the characters. Consider the following code:

String myString = "I'm a string.";

String anotherString = "I'm a string, too.";

String oneMoreString = "I'm a string.";

myString.equals(oneMoreString); //this will evaluate as TRUE

myString.equals(anotherString); //this will evaluate as FALSE

EQUALS VERSUS ==


At this point, you might have tried to do something like the following:

String abc = "the letters a, b and c";

if (abc == "the letters a, b and c"){

System.out.println("Strings are equal");

}

Notice that Java actually prints out that the string abc equals “the letters a, b and c”. So why do you need to use the equals() method?

The reasoning behind this is a bit tricky. For objects, it is perfectly fine to use == and != to compare them, but note that Java will not check whether the two objects are equal in the sense that they contain the same contents, but rather whether they reference the same position in memory.

The following code sample shows this in a clearer way:

String abc = "the letters a, b and c";

String xyz = abc;

if(abc == xyz)

System.out.println("Both refer to the same memory address");

However, in some cases the use of == actually leads to the expected result when checking the contents of a string. The reason behind this is due to the way the Java Virtual Machine handles strings. Java makes use of a concept called “interning” to reduce memory overhead when working with strings. This is particularly tricky if you try to outsmart the JVM optimizer by instantiating two strings like this:

String abc = "the letters a, b and c";

String xyz = "the letters a, b and c";

if(abc == xyz){

System.out.println("Refers to same string");

} else {

System.out.println("Refers to different strings");

}

if(abc.equals(xyz)){

System.out.println("Contents of both strings are same");

} else {

System.out.println("Contents of strings are different");

}

The interning mechanism in Java is smart enough to detect that these two strings have the same value and can thus be represented by only one object. Hence, both == and equals() will evaluate as being true. However, the JVM has its limits in terms of how smart it is, so the following code sample will not work with ==:

String abc = "the letters a, b and c";

String xyz = "the letters a, b";

xyz = xyz + " and c";

if(abc == xyz) {

System.out.println("Refers to same string");

} else {

System.out.println("Refers to different strings");

}

if(abc.equals(xyz)) {

System.out.println("Contents of both strings are same");

} else {

System.out.println("Contents of strings are different");

}

In practice, there exist few cases where you want to check whether two objects (and strings in particular) refer to the same in-memory address compared to checking its contents. The best practice is thus to make sure to always use equals() when comparing string contents.

Similarly, the Arrays class implements a static equals() method. However, the syntax is different, and if you use the same format as for strings, the result will not be as you expect. When comparing the equality of two arrays, you want to test whether the sequence of elements matches in both arrays. For that, use this construct: Arrays.equals(array1,array2).

int[] myIntArray = {1,2,3};

int[] anotherIntArray = {1,2,3};

int[] oneMoreIntArray = {2,4,6};

int[] andAnother = {2,1,3};

Arrays.equals(myIntArray, anotherIntArray); //evaluates TRUE

Arrays.equals(myIntArray, oneMoreIntArray); //evaluates FALSE

Arrays.equals(myIntArray, andAnother); //evaluates FALSE

For relational comparisons, the String class implements a compareTo() method from the Comparable interface. Interfaces are discussed in Chapter 6, but essentially, interfaces are like class outlines that specify what a class should do, but not how to do it. Comparable is one such outline that offers methods to compare objects. String’s compareTo() method compares two strings lexicographically, similar to how words or phrases would be sorted alphabetically. If the first string comes first alphabetically, the method will return a negative integer, indicating the first is less than the second. If the first operand comes last alphabetically, the method will return a positive integer, indicating the first is greater than the second. If the two strings are equal, the method will return 0. IfmyString.equals(anotherString) evaluates to true, then myString.compareTo(anotherString) will return 0. An example using the compareTo() method follows:

String employee1 = "Addams";

String employee2 = "Brown";

String employee3 = "O'Connor";

String manager = "Brown";

employee1.compareTo(employee2); //evaluates to -1 (negative)

employee3.compareTo(employee2); //evaluates to 13 (positive)

employee2.compareTo(manager); //evaluates to 0

There is not a similarly straightforward approach to comparing arrays relationally, partially because there is not one single way to rank one set of elements against another. Also, the elements of an array can be any type of object. You can think of many criteria that might determine which int array is greater than another: the greatest length, the greatest sum of all elements, the greatest single element, and so on, and that is only for int arrays. Arrays of more complex objects require even more unique criteria. Relational comparisons of arrays, like many other objects, must be defined according to the needs of the program.

UNDERSTANDING LANGUAGE CONTROL

This section explores how comparison operators and methods can be used in Java control structures. These structures include for and while loops, if-then statements, and switches. While each situation may be better suited to one type of structure, in fact, they are usually interchangeable as they function much the same way using different constructs. The following sections explain each of these structures independently and also compare and contrast them.

Creating if-then Statements

The most fundamental control structure is an if-then statement. Simply put, if a condition is met, then execute a piece of code. It may also be called branching, since different branches of code are executed according to the conditional statements. Often a control operator will be used as the condition in an if-then statement. The most basic syntax is as follows:

if (/*condition*/) {

/*then execute these statements*/

}

In this case, if the conditions inside the parentheses are evaluated as true, then the statements between curly brackets will be executed. Otherwise, the program will not execute the statements and continue just after the last curly bracket, indicating the end of the block.

NOTE If there is only a single statement following the if condition, the curly brackets are optional. It is recommended to use the brackets, even when unnecessary, both to make it more clear to someone reading the code and also to improve maintainability. For instance, if you (or another programmer) later add additional statements to the if-then statement, you will not risk forgetting to place brackets around the entire block at that time.

For a concrete example of if-then statements, imagine a banking program that prints a short notification at the bottom of each ATM transaction receipt according to the remaining balance on the account. This example prints to the console for simplicity’s sake.

if (accountBalance > 100) {

System.out.println("Safe balance.");

}

If the value of the variable accountBalance is greater than 100, then output a notification of "Safe balance." to the console. If accountBalance is not greater than 100, nothing will happen.

The basic if-then statement can also be extended with the keyword else. This provides an alternative set of statements to be executed if the condition is not true.

if (accountBalance > 100) {

System.out.println("Safe balance.");

} else {

System.out.println("Warning: Low balance.");

}

Now, if accountBalance is greater than 100, the same notification will be printed. However, if accountBalance is less than or equal to 100, a different notification will be printed.

The else keyword can also be followed by a second if statement, which is then evaluated only if the first condition is false.

if (accountBalance > 100) {

System.out.println("Safe balance.");

} else if (accountBalance < 0){

System.out.println("ALERT: Negative balance!");

} else {

System.out.println("Warning: Low balance.");

}

The first if condition is evaluated if accountBalance is greater than 100, at which point the "Safe balance." notification will print and nothing further is executed. If accountBalance is not greater than 100, the second if condition is evaluated. If accountBalance is less than0, the ALERT will be printed and nothing further will be executed. If accountBalance is not less than 0, that is, if accountBalance is between 0 and 100, the warning will be printed, and the end of the statement is reached.

Nesting if-then Statements

Control structures, such as if-then statements, can also be nested. This means that one if-then statement is inside another if-then statement, as if the outer statement formed a nest for the inner statement. This concept looks something like the following:

if (accountBalance > 0) {

System.out.println("Safe balance.");

if (accountDays > 90) {

System.out.println(savingsAccountOffer);

}

} else {

System.out.println("ALERT: Negative balance!");

}

This is an example of nested if-then statements because the if (accountDays > 90) statement is nested inside the if (accountBalance > 0)statement. This program will first check if the account balance is greater than zero. If it is greater than zero, it will print a safe balance notification and then check if the account has been active more than 90 days. If this is also true, then an offer to open a savings account will also be printed. However, if the account balance is not greater than zero, the negative balance alert will be printed and the accountDays variable will never be evaluated.

This could also be accomplished using the Boolean operators discussed earlier in this chapter. That approach would look like this:

if (accountBalance > 0 && accountDays <= 90) {

System.out.println("Safe balance.");

} else if (accountBalance > 0 && accountDays > 90) {

System.out.println("Safe balance.");

System.out.println(savingsAccountOffer);

} else {

System.out.println("ALERT: Negative balance!");

}

You will notice that the "Safe balance" print command is repeated for the first two if-then statements. That means if you want to adjust the statement that is printed whenever a balance is over zero, or if you want to add and change any other actions to perform when the balance is greater than zero, you would have to make those changes in both places.

If you have more than two conditions to evaluate, you can nest deeper than two levels. To maintain readability, the closing bracket (}) should be lined up vertically with the if keyword it closes.

if (accountBalance > 0) {

System.out.println("Safe balance.");

if (accountDays > 90) {

System.out.println(savingsAccountOffer);

if (creditAccounts > 1) {

balanceTransferPossible = true;

} else {

sendCreditApplication();

}

}

} else {

System.out.println("ALERT: Negative balance!");

}

If you wanted to accomplish the same with Boolean operators, it would require an if-then statement for every combination of conditions.

if (accountBalance > 0 && accountDays <= 90) {

System.out.println("Safe balance.");

} else if (accountBalance > 0 && accountDays > 90 && creditAccounts > 1) {

System.out.println("Safe balance.");

System.out.println(savingsAccountOffer);

balanceTransferPossible = true;

} else if (accountBalance > 0 && accountDays > 90) {

System.out.println("Safe balance.");

System.out.println(savingsAccountOffer);

sendCreditApplication();

}

} else {

System.out.println("ALERT: Negative balance!");

}

This can quickly become unwieldy, first to program and even more so for maintenance later. For these reasons, a set of nested if-then statements can often be a better alternative.

Creating for Loops

Loops, as the name suggests, are structures that cycle through a section of code as long as some condition is met. This allows for repetitive execution without repetitive coding. It reduces redundancy, which improves the maintainability of code, but perhaps more importantly, it allows for flexibility since the number of times a program loops can change according to the specific conditions present during a certain execution. Imagine you run a small business and have last year’s sales figures and staff numbers for each month stored in int arrays. You would like to calculate the average sales per staff member for each month and the total annual sales for the year.

int[] sales2014 = {500,720,515,377,400,435,510,1010,894,765,992,1125};

int[] staff2014 = {7,5,5,5,5,6,6,7,7,8,9,9};

int[] salesPerStaff = new int[12];

int totalSales2014 = 0;

salesPerStaff[0] = sales2014[0]/staff2014[0];

salesPerStaff[1] = sales2014[1]/staff2014[1];

salesPerStaff[2] = sales2014[2]/staff2014[2];

salesPerStaff[3] = sales2014[3]/staff2014[3];

salesPerStaff[4] = sales2014[4]/staff2014[4];

salesPerStaff[5] = sales2014[5]/staff2014[5];

salesPerStaff[6] = sales2014[6]/staff2014[6];

salesPerStaff[7] = sales2014[7]/staff2014[7];

salesPerStaff[8] = sales2014[8]/staff2014[8];

salesPerStaff[9] = sales2014[9]/staff2014[9];

salesPerStaff[10] = sales2014[10]/staff2014[10];

salesPerStaff[11] = sales2014[11]/staff2014[11];

totalSales2014 = sales2014[0]+sales2014[1]+sales2014[2]+sales2014[3]

+sales2014[4]+sales2014[5]+sales2014[6]+sales2014[7]+sales2014[8]+sales2014[9]

+sales2014[10]+sales2014[11];

You can immediately spot the redundancy in this code. To find a better solution, simply describe what it is you would like to do. For every month of the year, divide the sales by the staff and sum the sales. In order to implement this in Java, you can use a for loop. Afor loop executes a block of code over a range of values. An index variable keeps track of the loop. The standard syntax for a for loop is as follows:

for (/*Initialization*/; /*Termination*/; /*Increment*/){

/*execute these statements*/

}

Rather than just a condition as you saw in the if-then statement, for loops require three parts. Initialization declares the index variable for the loop and its starting value; commonly this is int i = 0. Termination specifies a stopping criterion, or maximum value for the index variable. Increment indicates how the index variable should change after each iteration, commonly this is i++, meaning that the value of i will increase by one after each loop. Alternatively, you can use i– for the increment and a minimum value in the termination; in this way your looping will count down, rather than up. Finally, all the statements that should be executed during each loop are placed between the curly brackets.

You can implement the previous example in the following for loop:

int[] sales2014 = {500,720,515,377,400,435,510,1010,894,765,992,1125};

int[] staff2014 = {7,5,5,5,5,6,6,7,7,8,9,9};

int[] salesPerStaff = new int[12];

int totalSales2014 = 0;

for (int i=0; i<sales2014.length; i++){

salesPerStaff[i] = sales2014[i]/staff2014[i];

totalSales2014 = totalSales2014 + sales2014[i];

}

This for loop starts with an index value of 0 and evaluates salesPerStaff at month 0 and totalSales2014 at month 0. At the end of this iteration of the loop, the index increments to 1, and those same variables are evaluated for month 1 and so on, until month 11. The value of sales2014.length is the number of elements in the sales2014 array, which is 12. So when the index increments to 12, it will evaluate i<sales2014.length as false, and the looping will terminate.

There are several benefits to this improved loop implementation. You might notice it is easier to read and less prone to typing errors than the longer and more tedious version. Recall that loops improve maintainability and flexibility. Now that you have an example, it might be easier to visualize the impact of these factors. Easier maintenance means that future changes to the application are easier to implement. If you needed to change how SalesPerStaff is calculated, you would have to make 12 changes in the first version versus only one in the for loop. The flexibility of loops is based on the self-determined termination criteria. In the example, the loop iterates 12 times, because the array has 12 elements. Now imagine your company begins recording weekly sales instead of monthly sales, increasing the elements of the sales array from 12 to 52 per year. In the first version of the program, the number of statements would increase by the same amount, also increasing the chance of errors. However, the for loop in the second version would accommodate arrays of any length without need for manual modification.

You can also leave either the initialization or increment blank in a for loop. In this case, you would need to specify the variable before the for loop or the increment during the for loop. Following are two examples that function the same as the previous example, but with a slightly different syntax.

int[] sales2014 = {500,720,515,377,400,435,510,1010,894,765,992,1125};

int[] staff2014 = {7,5,5,5,5,6,6,7,7,8,9,9};

int[] salesPerStaff = new int[12];

int totalSales2014 = 0;

int i = 0; //specify initialization variable here, not before termination

for ( ; i<sales2014.length; i++){

salesPerStaff[i] = sales2014[i]/staff2014[i];

totalSales2014 = totalSales2014 + sales2014[i];

}

int[] sales2014 = {500,720,515,377,400,435,510,1010,894,765,992,1125};

int[] staff2014 = {7,5,5,5,5,6,6,7,7,8,9,9};

int[] salesPerStaff = new int[12];

int totalSales2014 = 0;

for (int i=0; i<sales2014.length; ){

salesPerStaff[i] = sales2014[i]/staff2014[i];

totalSales2014 = totalSales2014 + sales2014[i];

i = i + 1; //specify increment here, not after termination

}

It is important to keep your termination condition and increment direction in mind when you are setting up a for loop. You could unintentionally create an infinite loop by having these misaligned. For example, imagine the following for loop: for (int i = 5; i > 0; i++). Your loop will continue to repeat indefinitely. The starting value for i is 5, which is greater than 0, and the value of i will continue increasing as you loop, so it will always remain greater than 0. In general, a termination condition using > will have an increment using --, and a termination condition using < will have an increment using ++.

Another consideration is how your iterator may be altered within the for loop. It is possible to reassign the value of your iterator as part of the loop, instead of or in addition to the increment expression. Consider adding a line to the example.

int[] sales2014 = {500,720,515,377,400,435,510,1010,894,765,992,1125};

int[] staff2014 = {7,5,5,5,5,6,6,7,7,8,9,9};

int[] salesPerStaff = new int[12];

int totalSales2014 = 0;

for (int i=0; i<sales2014.length; i++){

i = i*2; //this line is added

salesPerStaff[i] = sales2014[i]/staff2014[i];

totalSales2014 = totalSales2014 + sales2014[i];

}

Here, the value of i is changed as part of the increment and also within the loop. So the loop will be processed in the following way:

1. Start at the beginning of the for loop. i=0 and 0 < 12, so the loop is entered.

2. i=i*2 or i = 0*2 = 0, so the statements are evaluated on the 0 (first) element of each array.

3. At the end of the for loop, i is incremented to i++ or i=1.

4. Return to the start of the for loop. i=1 and 1 < 12, so the loop is entered a second time.

5. i=i*2 or i = 1*2 = 2, so the statements are evaluated on the 2 (third) element of each array.

6. At the end of the for loop, i is incremented to i++ or i=3.

7. Return to the start of the loop. i=3 and 3 < 12, so the loop is entered a third time.

8. i=i*2 or i = 3*2 = 6, so the statements are evaluated on the 6 (seventh) element of each array.

9. At the end of the for loop, i is incremented to i++ or i=7.

10.Return to the start of the loop. i=7 and 7 < 12, so the loop is entered a fourth time.

11.i=i*2 or i = 7*2 = 14, so the statements should be evaluated on the 14 (fifteenth) element of each array. However, there are only twelve elements in each array. Here you will run into an error and the program will be terminated.

In short, a for loop is a control structure that lets you repeat a certain block of code a specified number of times. The amount of times can be determined in advance or dynamically, depending on the situation. When creating a for loop, pay attention to the initialization, termination, and increment specified to be sure you are not creating infinite loops or errors at execution.

TRY IT OUT Your First for Loop

To create a simple for loop, follow these steps:

1. Create a new project in Eclipse. Perhaps call it Chapter5 to keep the exercises organized according to the chapters in this book.

2. Create a new class by right-clicking on the src folder in your new project. Select New and then Class.

3. In the Name field, enter the name of your class, ForLoop, beginning with a capital letter by Java convention. In the bottom portion of the New Java Class window, there is a section that reads: “Which method stubs would you like to create?” You may choose to check the box next to “public static void main(String[] args)” to automatically create a main method.

4. You should automatically have the basis for the class body shown here:

5. public class ForLoop {

6. /**

7. * @param args

8. */

9. public static void main(String[] args) {

10. // TODO Auto-generated method stub

11.

12. }

}

If not, you can type it yourself. You do not need the comments denoted with /** or //. In Eclipse, they appear as blue or green text. Comments are useful for explaining what the code is doing, but are never compiled or executed by Java.

public class ForLoop {

public static void main(String[] args){

}

}

13. Recall that the main method provides the starting point and ordering for the execution of your program. Inside the main method, create a for loop as follows:

14. for (int i = 1; i <= 10 ; i++){

15.

}

It should be placed after (String[] args){ and before the next }.

16. Now insert the statements that will be executed during each loop. On each iteration, you will multiply the value of i by 2 (doubling it) and then print a string containing the resulting value to the console. Use the following statements to do so:

17. int doubled = i * 2;

System.out.println(i + " times two equals " + doubled);

Place these between the { } of the for loop.

18. Finally, add a print statement to indicate the end of the program. Use the following statement:

System.out.println("End of program");

This time, make sure it is placed after the closing bracket (}) of the for loop, but before the closing bracket (}) of the main method. This ensures that it will not be repeated on each iteration, but it will be executed once before the main method concludes.

19. Your class body should now look like this:

20. public class ForLoop {

21.

22. public static void main(String[] args){

23. for (int i = 1; i <= 10; i++){

24. int doubled = i * 2;

25. System.out.println(i + " times two equals " + doubled);

26. }

27. System.out.println("End of program");

28. }

}

29.Save the class by clicking the disk icon or selecting File, then Save.

30.Run the application by clicking the green play icon or selecting Run, and then Run.

How It Works

Now take a look at how it works.

1. The application begins by executing the main method, which in this case is the only method.

2. The first statement begins with a for loop.

3. The iterator, named i, begins at value 1 and checks the termination condition. 1 is less than or equal to 10, so you enter the loop.

4. In the first statement inside the loop, a second int, named doubled, is assigned the value of i*2. In this first iteration, i = 1, so doubled = 2.

5. In the next statement of the loop, there is a println command. A line is output to the console that reads: 1 times two equals 2. Because the command is println instead of print, you can imagine pressing Enter or Return at the end of the string to create a new line.

6. The program reaches the end of the loop, and because the iteration of the loop is i++, 1 is added to the value of i. The iterator i is reassigned the value of 1+1 or 2.

7. The termination condition is evaluated again. Because 2 is still less than or equal to 10, you will go through the loop again.

8. The variable doubled is 2*2 or 4 this time.

9. Another line will be output to the console, this time reading: 2 times two equals 4.

10.This will continue until i++ = 11, when the termination condition will evaluate to false and the loop will not be entered anymore. At that time, the loop will be skipped over and the program will proceed with the final statement. One final line will be output to the console, indicating the end of the program.

What Is an Enhanced for Loop?

There is an alternate form, called an enhanced for loop, that was introduced specifically for arrays and other iterable objects. Instead of the index initialized as part of the standard for loop, enhanced for loops use an iterator. Unlike the index of a standard for loop, the iterator does not require initialization, termination, or increment, as it will automatically iterate through all elements in the array. Note that rather than an integer index, the iterator is the same type as the elements in the array or other Iterable object. From the previous example, this second form would be coded as follows:

for (int i: sales2014){

salesPerStaff[i] = sales2014[i]/staff2014[i];

totalSales2014 = totalSales2014 + sales2014[i];

}

This can be read in English as, “For each int in the sales2014 array, do the following. . .” The array can contain other data types or objects.

NOTE Enhanced for loops allow automatic iteration over arrays and other iterable objects.

Here’s a second example using strings instead of ints. It follows the same pattern as before, “For each string in the nameList array, print that string.”

String[] nameList = {"Adam Brown","Betsy Dudley","Carl Frank"};

for (String name: nameList){

System.out.println(name);

}

Enhanced for loops offer the same functionality of regular for loops with a format that’s easier to code and read. They do require a data structure that’s iterable, but if you are working with arrays, they may provide a handy solution for you.

TRY IT OUT Try It Out: An Enhanced for Loop

To create an enhanced for loop, follow these steps:

1. Create a new class named EnhancedForLoop, following the process you learned about earlier. You can continue to use the same Chapter5 project. Create a new class by right-clicking on the src folder in your project. Select New and then Class.

2. In the Name field, enter the name of your class, EnhancedForLoop, beginning with a capital letter by Java convention. In the bottom portion of the New Java Class window, there is a section that reads: “Which method stubs would you like to create?” You may choose to check the box next to “public static void main(String[] args)” to automatically create a main method.

3. You should automatically have the basis for the class body shown here:

4. public class EnhancedForLoop {

5. /**

6. * @param args

7. */

8. public static void main(String[] args) {

9. // TODO Auto-generated method stub

10.

11. }

}

If not, you can type it yourself. You do not need the comments, which are denoted with /** or //. In Eclipse, they will appear as blue or green text. Comments are useful for explaining what the code is doing, but are never compiled or executed by Java.

public class EnhancedForLoop {

public static void main(String[] args){

}

}

12. Recall that the main method provides the starting point and ordering for the execution of your program. An enhanced for loop will iterate through the elements of an array, but first you must declare an array for this:

int[] tenIntegers = {1,2,3,4,5,6,7,8,9,10};

It should be placed after (String[] args){ and before the next }.

13. Now add the following enhanced for loop immediately after the array declaration.

14. for (int i : tenIntegers){

15.

}

16. Now insert the statements that will be executed during each loop. On each iteration, you will multiply the value of the current array entry by 2 (doubling it) and then print a string containing the resulting value to the console. Use the following statements to do so:

17. int doubled = i * 2;

System.out.println(i + " times two equals " + doubled);

Place these statements between the{ } of the for loop.

18. Finally, add a print statement to indicate the end of the program. Use the following statement:

System.out.println("End of program");

This time, make sure it is placed after the closing bracket (}) of the for loop, but before the closing bracket (}) of the main method. This ensures that it will not be repeated on each iteration, but it will be executed once before the main method concludes.

19. Your class body should now look like this:

20. public class EnhancedForLoop {

21.

22. public static void main(String[] args){

23. for (int i : tenIntegers){

24. int doubled = i * 2;

25. System.out.println(i + " times two equals " + doubled);

26. }

27. System.out.println("End of program");

28. }

}

29.Save the class by clicking the disk icon or selecting File, then Save.

30.Run the application by clicking the green play icon or selecting Run, and then Run.

How It Works

Now take a look at how it works.

1. The application begins by executing the main method, which in this case is the only method.

2. The first statement creates a new integer array with ten entries.

3. The next statement opens an enhanced for loop, which will iterate through all the entries of the array. In a regular for loop, the iterator is generally an integer. In an enhanced for loop, it takes the same type as the array entries. In this case, it is an integer because the array is an int[ ]. You use the name of the iterator to refer to the current entry within the loop. In the first iteration, i takes the value of the first entry of the array, in this case 1. On the next iteration, it will take the value of the next entry, 2.

4. In the first statement inside the loop, a second int, named doubled, is assigned the value of i*2. In this first iteration, i = 1, so doubled = 2.

5. In the next statement of the loop, there is a println command. A line is output to the console that reads: 1 times two equals 2. Because the command is println instead of print, you can imagine pressing Enter or Return at the end of the string to create a new line.

6. When the program reaches the end of the loop, it will restart the loop with the next entry in the array. The iterator i is reassigned the value of the second array entry, in this case 2.

7. The variable doubled is 2*2 or 4 in this iteration of the loop.

8. Another line will be output to the console, this time reading: 2 times two equals 4.

9. This will continue until every entry in the array has been used. Then, the program will proceed with the final statement. One final line will be output to the console indicating the end of the program.

10.If you executed the for loop in the previous Try It Out exercise, you’ll notice that they produce the same output. The two types of for loops work in much the same way, but in some situations one will be preferable to the other. In this enhanced forloop exercise, it was probably unnecessary to create an array just to list the integers between 1 and 10; a standard for loop does this simply by incrementing the iterator by 1 on each loop. For an array of strings or other objects, iterating through the array in an enhanced for loop may be simpler to code and easier to read.

Nesting for Loops

As you saw with if-then statements, for loops can also be nested. The format is very similar, where one inner for loop is contained within another outer for loop. The general appearance is as follows:

for (/*Initialization*/; /*Termination*/; /*Increment*/){ //outer loop

/*execute these statements*/

for (/*Initialization2*/; /*Termination2*/; /*Increment2*/){ //inner loop

/*execute these statements*/

} //close inner loop

} //close outer loop

Because the statements inside the inner for loop can refer to the iterator of both the inner loop and outer loop, it’s necessary to use different variable names in the initialization of each loop. You’ve probably noticed that many of the standard for loops shown in this chapter use x as the index name (and x = 0 as the initialization); this is by no means required, but is often used in practice. Similarly, x and y are often used as index names in nested for loops. You will often encounter the use of nested for loops to iterate through a matrix of values. Here is an example of that type to demonstrate the use of nested for loops.

Suppose you run a small business with three employees. You store the hours worked by each employee in a matrix like the one shown in Table 5.3.

Table 5.3 Weekly Hours Worked by Employee

EMPLOYEE

MONDAY

TUESDAY

WEDNESDAY

THURSDAY

FRIDAY

Chris

3

2

8

2

3

Danielle

4

4

4

4

4

Michael

5

5

0

5

5

By using nested for loops, you can iterate through all the entries of this matrix, where the position (0,0), first row and first column, refers to the hours worked by Chris on Monday, and position (1,3), second row and fourth column, refers to the hours Danielle worked on Thursday. One for loop will refer to the column and the other will refer to the row.

int[][] hoursWorked = {{3,2,8,2,3},{4,4,4,4,4,4},{5,5,0,5,5}};

String[] employees = {"Chris", "Danielle", "Michael"};

double wage = 8.30;

for (int x = 0; x < hoursWorked.length; x++){ //outer for loop

System.out.print(employees[x] + " worked ");

int weeklyHours = 0;

for (int y = 0; y < hoursWorked[0].length; y++){ //inner for loop

weeklyHours += hoursWorked[x][y];

} //close inner for loop

System.out.println(weeklyHours + " hours at " + wage + " per hour.");

double weeklyPay = weeklyHours * wage;

System.out.println("Weekly Pay: " + weeklyPay);

} //close outer for loop

The two-dimensional int array hoursWorked represents the matrix shown in Table 5.3. Each row is a one-dimensional int array with five elements. A string array employees stores the names of the three employees. A double represents the hourly wage paid to employees. Here all employees receive the same pay, but if they are different, there could be a double array set up similarly to the array for names.

The outer loop iterates three times, one for each row in the matrix, in other words, once for each employee. When x = 0, this refers to the first row of the matrix and the first element in all the arrays. Remember, in hoursWorked, the first element is itself an array. First, you print the employee’s name to the console. Note, this is a print command, rather than println, so whatever is printed next will continue on the same line. Then you initialize weeklyHours to zero. This is an important step to do inside the outer for loop; this “resets” the value to zero each time you change employee by incrementing the outer for loop. If you initialize this variable outside of the for loops, like the wage variable, it will continue adding all the employees’ hours together.

Then the inner for loop begins. One important difference here is the termination condition. In the outer for loop, you stop when the iterator exceeds the length of the hoursWorked array, that is, the number of elements or number of employees, which is 3. In the innerfor loop, you stop when the iterator exceeds the length of the first element of the hoursWorked array, that is the number of elements in the array, which is the first element or the number of days in the week (which is 5).

Inside the inner for loop, you simply add each day’s hours to the total weeklyHours for the current employee. After the five iterations for each day of the week, you exit the inner for loop.

Now, you are still inside the outer for loop, but have calculated the hours from the inner for loop. The weeklyHours value is printed as well as the wage. Since that was a println command, the next print statement will begin on a new line. The weekly pay is calculated by multiplying the hours by the wage and this is printed on a new line. This concludes the outer loop, so the program will increment the value of x by 1 and return to the start of the outer loop. After three iterations, one for each employee, this part of the program will be done. If you put all of this inside the main method of a class, it is executable.

Creating while Loops

A while loop is an alternative loop structure that’s based on meeting a certain condition, rather than iterating a set number of times. The standard syntax of a while loop is as follows:

while (/*conditional expression*/) {

/*execute these statements*/

}

Remember the difference between a for loop and an enhanced for loop: the for loop iterator is initialized in the loop expression, but in an enhanced for loop, an array must be declared somewhere prior to entering the for loop. A while loop is similar to the enhancedfor loop in this way. You will need to initialize some variable before the while loop that will be evaluated as part of the conditional expression.

When the execution of a program reaches a while loop, it will first check to see if the conditional expression evaluates to true. If so, it will enter the loop and execute the statements inside the loop. When the end of loop is reached, it will return to the conditional expression and check if it still evaluates to true. If so, the loop will be repeated. It should be clear, then, that evaluation of the conditional statement should change at some point during the looping process. Otherwise, the loop iterations will never end. Consider the following code example:

int i = 10;

while (i > 0){

System.out.println(i);

}

Here, the integer i is given the value of 10. When the while loop is first encountered, the conditional expression i > 0 is evaluated: 10 is greater than 0, so the expression is true. The program outputs "10" to the console, then returns to the start of the while loop again. The conditional expression i > 0 is evaluated again, but i is still equal to 10 and 10 is greater than 0 so the expression is still true. Again, you’ll see an output of "10" to the console. This will continue indefinitely, creating an infinite loop. To prevent this, you can add a statement inside the while loop to alter the value of the variable i.

int i = 10;

while (i > 0){

System.out.println(i);

i = i - 1;

}

This time, the conditional expression 10 > 0 is still true when the while loop is first encountered. During the first iteration, the output "10" will be printed to the console, then int i will be reassigned the value i-1 or 9. The conditional expression will be evaluated again to true, so the loop will be repeated. Now 9 will be output to the console and int i will be reassigned the value 8. This will continue until i = 0, when the expression will evaluate to false.

It’s possible that your conditional expression is not a variable at all. You will see some classic examples of while loops in Chapter 7 when dealing with inputs and outputs. For now, it’s enough to understand that the Scanner class has two methods, hasNextLine() andnextLine(), that can be used when scanning files, to determine if a file still has more lines to be scanned, and to actually scan the next line, respectively.

int lines = 0;

while (myScanner.hasNextLine()){

lines++;

}

This code might look like it will count the number of lines in the file being scanned by myScanner. However, this will actually create an infinite loop like the first while loop you saw. That’s because the program never moves past the first line of the file. When the loop is first encountered, assuming the file has at least one line in it, the conditional expression hasNextLine() will evaluate to true. The variable lines will be reassigned the value 0+1 or 1 and the conditional expression will remain true. In order to ensure that the loop will end and the correct number of lines will be counted, you have to progress through the lines of the file using the nextLine() method.

int lines = 0;

while (myScanner.hasNextLine()){

myScanner.nextLine(); //scan the next line

lines++;

}

In this way, in each iteration of the while loop, the scanner will scan another line of the file until the end of the file is reached. Then, the conditional expression hasNextLine() will evaluate to false and the program will not enter the loop again.

TRY IT OUT Your First while Loop

To create a while loop, follow these steps:

1. Create a new class named WhileLoop, following the same process. You can continue to use the same Chapter5 project. Create a new class by right-clicking on the src folder in your project. Select New and then Class.

2. In the Name field, enter the name of your class, WhileLoop, beginning with a capital letter by Java convention. In the bottom portion of the New Java Class window, there is a section that reads: “Which method stubs would you like to create?” You may choose to check the box next to "public static void main(String[] args)" to automatically create a main method.

3. You should automatically have the basis for the class body shown here:

4. public class WhileLoop {

5. /**

6. * @param args

7. */

8. public static void main(String[] args) {

9. // TODO Auto-generated method stub

10.

11. }

}

If not, you can type it yourself. You do not need the comments, which are denoted with /** or //. In Eclipse, they will appear as blue or green text. Comments are useful for explaining what the code is doing, but are never compiled or executed by Java.

public class WhileLoop {

public static void main(String[] args){

}

}

12. Recall that the main method provides the starting point and ordering for the execution of your program. A while loop requires a variable to be initialized before the loop so that it can be evaluated as part of the conditional expression. Initialize an integer with the following statement:

int i = 1;

It should be placed after (String[] args){ and before the next }.

13. Now add the following while loop immediately following the int declaration.

14. while (i <= 10){

}

15. Now insert the statements that will be executed during each loop. In each iteration, you multiply the value of the current array entry by 2 (doubling it) and then print a string containing the resulting value to the console. Use the following statements to do so:

16. int doubled = i * 2;

System.out.println(i + " times two equals " + doubled);

Place these statements between the{ } of the while loop.

17. Remember, you must alter the value of the variable used in the conditional expression during the loop to avoid infinite looping. You may add it anywhere within the loop, but keep in mind that the statements are executed from top to bottom, so if you change the value of i before doubling and printing, you will double and print the new value. Add the following line after the System.out.println() line, but before the next }.

i++;

18. Finally, add a print statement to indicate the end of the program. Use the following statement:

System.out.println("End of program");

This time, make sure it is placed after the closing bracket (}) of the while loop, but before the closing bracket (}) of the main method. This ensures that it will not be repeated in each iteration, but it will be executed once before the main method concludes.

19. Your class body should now look like this:

20. public class WhileLoop {

21. public static void main(String[] args) {

22. int i = 1;

23. while (i <= 10){

24. int doubled = i * 2;

25. System.out.println(i + " times two equals " + doubled);

26. i++;

27. }

28. System.out.println("End of program");

29. }

}

30.Save the class by clicking the disk icon or selecting File, then Save.

31.Run the application by clicking the green play icon or selecting Run, and then Run.

How It Works

Now take a look at how it works.

1. The application begins by executing the main method, which in this case is the only method.

2. The first statement initializes an integer, named i, with the value of 1.

3. The next statement opens a while loop, which will loop based on the value of the integer i initialized in the previous statement.

4. In the first statement inside the loop, a second int, named doubled, is assigned the value of i*2. In this first iteration, i=1, so doubled=2.

5. In the next statement of the loop, there is a println command. A line is output to the console which reads: 1 times two equals 2. Because the command is println instead of print, you can imagine pressing Enter or Return at the end of the string to create a new line.

6. The last statement inside the while loop reassigns the value of i to i+1 or i=2.

7. When the program reaches the end of the loop, it will return to the conditional expression to see if it will enter the loop again. Since 2 is still less than 10, it will loop again.

8. The variable doubled is 2*2 or 4 in this iteration of the loop.

9. Another line will be output to the console, this time reading: 2 times two equals 4.

10.The integer i will be reassigned the value of i+1 or i=3.

11.This will continue until i=11 and then the conditional expression will evaluate to false. The while loop will be skipped on this last iteration and the program will continue below the loop.

12.One final line will be output to the console indicating the end of the program.

13.If you executed the for loops in the other Try It Out exercises in this chapter, you’ll notice that they all produce the same output. For these simple examples, the loops can be used somewhat interchangeably, with some small adaptations. You will encounter situations in the later chapters that are more suited to one type of loop over others.

What Is a do while Loop?

There is also an alternate form of a while loop that’s useful in some circumstances. It is called a do while loop and is very similar to the while loop. As you’ll recall, a while loop starts by evaluating a conditional statement, much like a for loop begins by checking the termination condition. A do while loop is different because it will first execute (“do”) the statements within the loop and then check the conditional expression (“while”) to see if it should repeat the loop. A standard do while loop uses the following syntax:

do {

/*execute these statements*/

} while (/*conditional expression*/);

To demonstrate the difference, consider the small example from the previous section of a while loop.

int i = 10;

while (i > 0){

System.out.println(i);

i = i - 1;

}

Now the same example is presented as a do while loop.

int i = 10;

do {

System.out.println(i);

i = i - 1;

} while (i > 0);

Now imagine you changed the conditional expression from i>0 to i<0. In the example with the while loop, you would first check the condition 10<0, which evaluates to false. The loop would be skipped and the program would continue below the while loop. In the second example with the do while loop, it would first execute the loop with i=10, then evaluate the condition 9<0 and find it to be false. The do while loop would not be repeated at this point.

A do while loop is useful when you want to ensure statements in the loop are executed at least the first time. It can be troublesome if it is possible to cause an error by executing the statements before checking the conditional expression. Consider the following example, which was used in the for loop section earlier:

int[] sales2014 = {500,720,515,377,400,435,510,1010,894,765,992,1125};

int[] staff2014 = {7,5,5,5,5,6,6,7,7,8,9,9};

int[] salesPerStaff = new int[12];

int totalSales2014 = 0;

for (int i=0; i<sales2014.length; i++){

salesPerStaff[i] = sales2014[i]/staff2014[i];

totalSales2014 = totalSales2014 + sales2014[i];

}

It is possible to implement this with a do while loop instead:

int[] sales2014 = {500,720,515,377,400,435,510,1010,894,765,992,1125};

int[] staff2014 = {7,5,5,5,5,6,6,7,7,8,9,9};

int[] salesPerStaff = new int[12];

int totalSales2014 = 0;

int i = -1;

do {

salesPerStaff[i] = sales2014[i]/staff2014[i];

totalSales2014 = totalSales2014 + sales2014[i];

i++;

} while (i<sales2014.length);

You must ensure that the variable i is initialized with a value that will refer to an element in the array. In the example, i=-1 will cause an error, as would i=12, because the arrays only have elements between 0 and 11.

TRY IT OUT A do while Loop

To create a do while loop, follow these steps:

1. Create a new class named DoWhileLoop, following the same process. You can continue to use the same Chapter5 project. Create a new class by right-clicking on the src folder in your project. Select New and then Class.

2. In the Name field, enter the name of your class, DoWhileLoop, beginning with a capital letter by Java convention. In the bottom portion of the New Java Class window, there is a section that reads: “Which method stubs would you like to create?” You may choose to check the box next to "public static void main(String[] args)" to automatically create a main method.

3. You should automatically have the basis for the class body shown here:

4. public class DoWhileLoop {

5. /**

6. * @param args

7. */

8. public static void main(String[] args) {

9. // TODO Auto-generated method stub

10.

11. }

}

If not, you can type it yourself. You do not need the comments, which are denoted with /** or //. In Eclipse, they will appear as blue or green text. Comments are useful for explaining what the code is doing, but are never compiled or executed by Java.

public class DoWhileLoop {

public static void main(String[] args){

}

}

12. Recall that the main method provides the starting point and ordering for the execution of your program. A do while loop requires a variable to be initialized before the loop so that it can be evaluated as part of the conditional expression. Initialize an integer with the following statement:

int i = 1;

It should be placed after (String[] args){ and before the next }.

13. Now add the following do while loop immediately following the int declaration.

14. do {

} while (i <= 10);

15. Now insert the statements that will be executed during each loop. On each iteration, you multiply the value of the current array entry by 2 (doubling it) and then print a string containing the resulting value to the console. Use the following statements to do so:

16. int doubled = i * 2;

System.out.println(i + " times two equals " + doubled);

Place these statements between the{ } of the do while loop.

17. Remember, you must alter the value of the variable used in the conditional expression during the loop to avoid infinite looping. You may add it anywhere within the loop, but keep in mind that the statements are executed from top to bottom, so if you change the value of i before doubling and printing, you will double and print the new value. Add the following line after the System.out.println() line, but before the next }.

i++;

18. Finally, add a print statement to indicate the end of the program. Use the following statement:

System.out.println("End of program");

This time, make sure it is placed after the closing bracket (}) of the while loop, but before the closing bracket (}) of the main method. This ensures that it will not be repeated on each iteration, but it will be executed once before the main method concludes.

19. Your class body should now look like this:

20. public class DoWhileLoop {

21. public static void main(String[] args) {

22. int i = 1;

23. do {

24. int doubled = i * 2;

25. System.out.println(i + " times two equals " + doubled);

26. i++;

27. } while (i <= 10)

28. System.out.println("End of program");

29. }

}

30.Save the class by clicking the disk icon or selecting File, then Save.

31.Run the application by clicking the green play icon or selecting Run, and then Run.

How It Works

Now take a look at how it works.

1. The application begins by executing the main method, which in this case is the only method.

2. The first statement initializes an integer named i with the value of 1.

3. The next statement opens a do while loop and enters the loop.

4. In the first statement inside the loop, a second int, named doubled, is assigned the value of i*2. In this first iteration, i=1, so doubled=2.

5. In the next statement of the loop, there is a println command. A line is output to the console which reads: 1 times two equals 2. Because the command is println instead of print, you can imagine pressing Enter or Return at the end of the string to create a new line.

6. The last statement inside the do while loop reassigns the value of i to i+1 or i=2.

7. When the program reaches the end of the loop, it will evaluate the conditional expression to see if it will return to the start of the loop again. Since 2 is still less than 10, it will loop again.

8. The variable doubled is 2*2 or 4 in this iteration of the loop.

9. Another line will be output to the console, this time reading: 2 times two equals 4.

10.The integer i will be reassigned the value of i+1 or i=3.

11.This will continue until i=11, and then the conditional expression will evaluate to false and it will not return to the start of the loop. Instead, the program will continue below the loop.

12.One final line will be output to the console indicating the end of the program.

13.If you executed the for loops in the other Try It Out exercises in this chapter, you’ll notice that they all produce the same output. For these simple examples, the loops can be used somewhat interchangeably, with some small adaptations. You will encounter situations in the later chapters that are more suited to one type of loop over others.

Comparing for and while Loops

As you’ve seen through the examples and exercises in the previous sections, for and while loops can both be used to obtain the same outcome. So how do you know which one to use?

For some problems, this will simply be a matter of preference. Some programmers tend to use for loops, except when a situation really demands a while loop. Others prefer while loops and include for loops only when needed. Many programmers, through practice and experience, learn a certain feeling for which one is best suited for the problem at hand, and you will too.

In general, keep in mind the following points:

· If you are iterating over a collection, consider a for loop first.

· If you know the number of loops in advance, consider a for loop first.

· If you don’t know the number of iterations, but the number will depend on a certain condition, consider a while loop first.

When making your decision, simplicity and clarity are important considerations. You want a solution that’s the simplest to code, for your own sake, and clearest to read and understand, for yourself and others who will have to maintain or reuse your code later.

Creating Switches

Earlier in this chapter, you learned that if-then statements are one of the basic control structures. Now you will see switch statements, which function in a similar way to if-then statements, but with a different syntax. They are particularly useful when you have severalelse clauses. A switch statement evaluates a single variable and, depending on its value, executes a certain block of code. The general syntax of a basic switch statement is as follows:

switch (/*variable*/ {

case 1: /*execute these statements*/; break;

case 2: /*execute these statements*/; break;

default: /*execute these statements*/;

}

The variable that’s evaluated can be a primitive byte, short, char, or int, as well as enumerated types and String. The switch checks the value of the variable for a match in one of the cases. If they are equal, the statements in that case will be executed.

NOTE Switches were extended in Java 7 to allow the use of strings as switch variables. To use a string as your variable and label, just include the label in quotation marks so it is recognized as a string. For example:

char initial;

String myName = "Bob";

switch (myName) {

case "Ann": initial = 'A'; break;

case "Bob": initial = 'B'; break;

case "Claire": initial = 'C'; break;

default: initial = '?'; break;

}

Notice the three new keywords in the syntax: case, break, and default. Cases are similar to the if() and else if() parts of an if-then statement. Each case is labeled with one possible value the variable might take. If the label matches the value of the variable, the statements that follow the : for that case will be executed. Cases are evaluated sequentially, from top to bottom. Once a match is found, all the statements to follow will be executed, even those intended for the other cases that follow. In order to prevent this from happening, the break keyword is used. The break keyword is discussed more in detail in the next section, but its purpose is to break out of the switch and continue with the rest of the program. default is the switch equivalent of the else clause in an if-then statement. If none of the explicit cases apply to the variable, default will still apply. Every value will match the default case, so this can be useful to handle unexpected situations.

Because a switch is organized into cases, it makes sense to use it when you have a finite number of expected values. Twelve months in a year, for example, could be represented by twelve cases. If the situation calls for a large range of values, it’s more suited to an if-then statement. Recall the example concerning bank account alerts, where depending on if accountBalance was less than 0, greater than 100, or somewhere in between, a message was displayed.

Imagine you want to include a switch in a bookkeeping program that determines the last day of each month for recording monthly income and expenses. It might look something like this:

int month = 4; // here 4 represents April

int lastDay;

boolean leapYear = false;

switch (month) {

case 1: lastDay = 31; break;

case 2: if (leapYear == true) {

lastDay = 29;

} else {

lastDay = 28;

} break;

case 3: lastDay = 31; break;

case 4: lastDay = 30; break;

case 5: lastDay = 31; break;

case 6: lastDay = 30; break;

case 7: lastDay = 31; break;

case 8: lastDay = 31; break;

case 9: lastDay = 30; break;

case 10: lastDay = 31; break;

case 11: lastDay = 30; break;

case 12: lastDay = 31; break;

default: lastDay = 0;

}

This can even be simplified because many of the cases result in the same outcome. As mentioned, cases are evaluated from top to bottom, and until the execution reaches a break keyword, the statements will continue to be executed. Notice how you can lump the months or cases together to treat a series of cases identically:

int month = 4; // here 4 represents April

int lastDay;

boolean leapYear = false;

switch (month) {

case 1:

case 3:

case 5:

case 7:

case 8:

case 10:

case 12:

lastDay = 31; break;

case 2:

if (leapYear == true) {

lastDay = 29;

} else {

lastDay = 28;

} break;

case 4:

case 6:

case 9:

case 11:

lastDay = 30; break;

default: lastDay = 0;

}

TRY IT OUT Creating a switch

To create a switch, follow these steps:

1. Create a new class named SwitchClass, following the same process. You can continue to use the same Chapter5 project. Create a new class by right-clicking on the src folder in your project. Select New and then Class.

2. In the Name field, enter the name of your class, SwitchClass, beginning with a capital letter by Java convention. In the bottom portion of the New Java Class window, there is a section that reads: “Which method stubs would you like to create?” You may choose to check the box next to "public static void main(String[] args)" to automatically create a main method.

3. You should automatically have the basis for the class body shown here:

4. public class SwitchClass {

5. /**

6. * @param args

7. */

8. public static void main(String[] args) {

9. // TODO Auto-generated method stub

10.

11. }

}

If not, you can type it yourself. You do not need the comments, which are denoted with /** or //. In Eclipse, they will appear as blue or green text. Comments are useful for explaining what the code is doing, but are never compiled or executed by Java.

public class SwitchClass {

public static void main(String[] args){

}

}

12. Recall that the main method provides the starting point and ordering for the execution of your program. A switch statement requires a variable to be initialized before the statement so that it can be evaluated for each of the cases. Initialize a string with the following statement:

String loanType = "Commercial";

It should be placed after (String[] args){ and before the next }.

13. In this example, you will use the value of the string to determine how to set the value of a double variable. In the next line, declare a double variable interestRate. It does not need its value initialized here.

double interestRate;

14. Now add the switch statement. Remember to use the loanType variable as the conditional expression.

15. switch(loanType){

16.

}

17. Now add your cases inside the switch statement.

18. case "Residential":

19. interestRate = 0.055;

20. break;

21. case "Commercial":

22. interestRate = 0.062;

23. break;

24. case "Investment":

25. interestRate = 0.059;

26. break;

27. default:

interestRate = 0;

Place these statements between the { } of the switch statement.

28. Next, add a print statement to show the outcome of the switch cases. Use the following statement:

29. System.out.println (loanType + " loans have an annual interest rate of "

+ interestRate*100 + "%.");

This time, make sure it is placed after the closing bracket (}) of the switch statement, but before the closing bracket (}) of the main method.

30. Your class body should now look like this:

31. public class SwitchClass {

32.

33. public static void main(String[] args) {

34. String loanType = "Commercial";

35. double interestRate;

36.

37. switch (loanType) {

38. case "Residential":

39. interestRate = 0.055;

40. break;

41. case "Commercial":

42. interestRate = 0.062;

43. break;

44. case "Investment":

45. interestRate = 0.059;

46. break;

47. default:

48. interestRate = 0;

49. }

50.

51. System.out.println(loanType + " loans have an annual interest rate of "

52. + interestRate * 100 + "%.");

53. }

}

54.Save the class by clicking the disk icon or selecting File, then Save.

55.Run the application by clicking the green play icon or selecting Run, and then Run.

How It Works

Now take a look at how it works.

1. The application begins by executing the main method, which in this case is the only method.

2. The first statement initializes a String, named loanType, with the value of "Commercial".

3. The next statement declares a double, named interestRate, but does not initialize it with any value.

4. Next, a switch statement is opened, using the variable loanType as the conditional expression. This means it will try to match the value of loanType to the values listed in each of the cases.

5. Next, the program will evaluate a series of cases, each in the same way. In the first case, it will compare "Commercial" to "Residential". Because they are unequal, it will move to the next case.

6. In the second case, it will compare "Commercial" to "Commercial". This time, because the two strings are equal, it will evaluate the statements associated with this case.

7. Inside the "Commercial" case, the value of interestRate will be set to 0.062. Then, the break statement will indicate that the switch statement should be interrupted and no further cases or statements will be evaluated. Without the break statement, the value of interestRate will be reassigned to 0.059 and again to 0 following all the statements in the rest of the switch statement.

8. After leaving the switch statement, the print statement will output a line of text to the console. The string that will be printed is composed of four parts:

o String loanType: Commercial

o String: loans have an annual interest rate of

o double interestRate*100: 0.062*100 = 6.2

o String: %.

o Altogether, the output will be: “Commercial loans have an annual interest rate of 6.2%.”

Comparing Switches and if-then Statements

Just like for and while loops are similar structures, switches and if-then statements are also easy to compare. When you are using a switch, you read it the same way as an if-then statement: if the value matches the case, then do something. So how do you know when to use each one?

As with the other control structures, there will be situations when either one is appropriate and you can choose according to your own preference. As you continue coding, your experience will tell you if a problem would be better solved with a switch or not.

In general, you might consider the following criteria:

· If you have a single variable that can take multiple values, a switch might be suitable.

· If you have multiple variables or conditions to consider, you will probably need an if-then statement.

· If the value you are considering can have a finite number of values, consider using a switch.

· If the variable can take any value within a continuous range of numbers, consider an if-then statement.

As before, try to keep simplicity and clarity in mind whenever you make decisions about how to code. You want a solution that’s simple for you to code, but also as clear to read and understand as possible, for yourself and others who will have to maintain or reuse your code later.

Reviewing Keywords for Control

Chapter 2 briefly covered Java keywords in a more general way. This section reviews keywords used in control structures. Many of these keywords have already been featured in this chapter, as they are specific to the types of control structures you’ve been reading about. Table 5.4 lists the control keywords and their associated control structures. This section focuses on break, continue, and return, which are more general and can be found in different kinds of structures.

Table 5.4 Control Keywords

KEYWORD

ASSOCIATED CONTROL STRUCTURE

for

for loop Enhanced for loop

while

while loop do while loop

do

do while loop

if

if-then statement

else

if-then statement

switch

switch statement

case

switch statement

default

switch statement

break

General use

continue

General use

return

General use

The last three keywords—break, continue, and return—all interrupt the execution of the current block of code. The differences among them is found in what happens after the interruption.

Controlling with the return Keyword

You have seen the return keyword as part of a return statement already, so it may seem strange to think of it as part of a control structure. You know that a return statement of a method completes the execution of that method by returning a value. So, whenever areturn statement is executed, that method is stopped, regardless of where in the list of statements it is placed. To imagine how this can be used for control, take the following example:

//array of employee ID numbers, stored as Strings

static String[] employees;

//method to search for a specified employee ID

static boolean findEmployee(String employeeID){

for (String emp : employees){

if (emp.equals(employeeID)){

return true;

}

}

return false;

}

As soon as the specified employeeID is found, the Boolean true will be returned. This will interrupt the search, whether it is the first string in the array, the last string, or anywhere in between. In this way, the flow of the program is controlled by the return statement.

It is also possible to use the return statement in the same way, but with a void method. In this case, the method will be interrupted, but no value will be returned.

import java.util.ArrayList;

static ArrayList<String> employeeList = new ArrayList< >();

//a method to add new Employees to the Employee array

static void addNewEmployee(String employeeID){

if (employeeList.contains(employeeID)){

return; //employee already exists

}

employeeList.add(employeeID);

}

In this example, if the employee is found in the ArrayList, then there is no need to put her into it. Therefore, the code returns nothing as soon as the employee is found and then exits the method.

Controlling with the break Keyword

The break keyword also interrupts the execution of the current block of code. You already saw this keyword used as part of the switch statement. It can also be used, in a similar way, with loop structures. A break could be thought of as a softer interruption than return, as the method continues to execute, just in a different place after breaking out of the current block. If break occurs as part of an iterative loop, the loop containing the break statement will be stopped and it will not complete any further iterations. In the following example, the use of the break keyword to exit a loop is shown.

//array of employee ID numbers, stored as Strings

static String[] employees;

//method to search for a specified employee ID

static void findEmployee(String employeeID){

String myString = employeeID + " was not found.";

for (String emp : employees){

if (emp.equals(employeeID)){

myString = employeeID + " was found.";

break;

}

}

System.out.println(myString);

}

Similar to the last example, as soon as the string is found in the array, if it is found, myString will be reassigned to indicate the employeeID was found. At that point, the enhanced for loop containing the break statement will stop looping and the program will resume after the curly bracket, which closes the for loop block. Then, the final print statement will be executed. If myString is never found in the array, the for loop will iterate through all elements of the array, exit the block in the same place, and then execute the same print statement, but the value of myString will be different.

Controlling with the continue Keyword

The continue keyword is the softest interruption, because only this particular iteration of the loop is stopped and the next iteration begins immediately. This is useful if there are statements you want to execute for only certain elements of an array or in specific iterations of the loop. To demonstrate, assume you have an array of Employee objects. Each Employee object has a method isManagedBy() to check if an ID value refers to the manager of that employee.

static Employee[] allEmployees;

static void printManagedBy(String managerID){

for (Employee emp : allEmployees){

if (!emp.isManagedBy(managerID)){

continue;

}

System.out.println(emp.getName());

}

}

Then the method printManagedBy() will loop through all Employee objects. If the current Employee is not managed by the ID specified, the current iteration will stop and the next Employee will be checked. If the current Employee is managed by the ID, the loop will continue to the print statement before proceeding to the next iteration.

Specifying a Label for break or continue Control

Both the break and continue keywords can be combined with a label in order to control the flow even more directly. Recall that using the break keyword without a label automatically interrupts the loop that most closely contains the break statement. If there are two nested for loops, the break statement would interrupt the inner for loop and resume at the outer for loop. By placing a label before the outer for loop and including that label in the break statement, you can force the break to apply to both loops at once.

To include a label in your program, simply choose a name for your label and insert it, followed by a colon (:), before the section of code you would like to break out of. For example, if you have a nested for loop and you would like a break in the inner for loop to break out of both for loops, your label would go before the first for keyword and the label name would follow the break keyword. Here’s the syntax for this:

outer: //label to break both for loops

for (/*Initialization*/; /*Termination*/; /*Increment*/){

for (/*Initialization*/; /*Termination*/; /*Increment*/){

/*execute these statements*/

break outer; //break with label

}

}

The following Try It Out exercise gives you some practice with the break keyword, both with and without labels.

TRY IT OUT Breaking a for Loop

Follow these steps to create three sets of nested for loops. The first is a standard for loop, the second has a break statement added, and the last one includes the break statement with a label.

1. Create a new class named BreakLoop, following the same process. You can continue to use the same Chapter5 project. Create a new class by right-clicking on the src folder in your project. Select New and then Class.

2. In the Name field, enter the name of your class, BreakLoop, beginning with a capital letter by Java convention. In the bottom portion of the New Java Class window, there is a section that reads: “Which method stubs would you like to create?” You may choose to check the box next to "public static void main(String[] args)" to automatically create a main method.

3. You should automatically have the basis for the class body shown here:

4. public class BreakLoop {

5. /**

6. * @param args

7. */

8. public static void main(String[] args) {

9. // TODO Auto-generated method stub

10.

11. }

}

If not, you can type it yourself. You do not need the comments, which are denoted with /** or //. In Eclipse, they will appear as blue or green text. Comments are useful for explaining what the code is doing, but are never compiled or executed by Java.

public class BreakLoop {

public static void main(String[] args){

}

}

12.Recall that the main method provides the starting point and ordering for the execution of your program. For this exercise, all the statements you want to execute will be inside the main method.

13. For the first nested for loop section, you use the standard syntax you saw earlier in the chapter. Begin with a print statement to display the area of the program that’s being executed. In each iteration of the nested loops, you will simply print the values for x and y, the variables you are using as iterators. Type the first nestedfor loop as follows:

14. System.out.println("\nLooping with No Break:");

15. for (int x = 0; x < 3; x++){ //outer loop (x loop)

16. for (int y = 0; y < 3; y++){ //inner for loop (y loop)

17. System.out.println("x = " + x + " and y = " + y);

18. }

}

19. Now add the second nested for loop section. This will include a break statement, which is executed whenever x and y have the same value. Type the second nested for loop as follows:

20. System.out.println("\nBreak with No Label:");

21. for (int x = 0; x < 3; x++){//outer loop (x loop)

22. for (int y = 0; y < 3; y++){ //inner loop (y loop)

23. System.out.println("x = " + x + " and y = " + y);

24. if (x == y) { //new conditional expression

25. System.out.println("Break out of y loop.\n");

26. break; //new break statement

27. }

28. }

}

29. Finally, add a third nested for loop section. This time, include both a break statement and a label. It will be executed under the same condition as the previous section. Type the third nested for loop as follows:

30. System.out.println("\nBreak with No Label:");

31. outer: // new label

32. for (int x = 0; x < 3; x++) {// outer loop (x loop)

33. for (int y = 0; y < 3; y++) { // inner loop (y loop)

34. System.out.println("x = " + x + " and y = " + y);

35. if (x == y) { // same conditional expression

36. System.out.println("Break out of both loops.\n");

37. break outer; // new break statement with label

38. }

39. }

}

40. All of the preceding for loops should be between the {} of the main method. Your class body should now look like this:

41. public class BreakLoop {

42. public static void main(String[] args) {

43. System.out.println("\nLooping with No Break:");

44. for (int x = 0; x < 3; x++) { // outer loop (x loop)

45. for (int y = 0; y < 3; y++) { // inner for loop (y loop)

46. System.out.println("x = " + x + " and y = " + y);

47. }

48. }

49.

50. System.out.println("\nBreak with No Label:");

51. for (int x = 0; x < 3; x++) {// outer loop (x loop)

52. for (int y = 0; y < 3; y++) { // inner loop (y loop)

53. System.out.println("x = " + x + " and y = " + y);

54. if (x == y) { // new conditional expression

55. System.out.println("Break out of y loop.\n");

56. break; // new break statement

57. }

58. }

59. }

60.

61. System.out.println("\nBreak with No Label:");

62. outer: // new label

63. for (int x = 0; x < 3; x++) {// outer loop (x loop)

64. for (int y = 0; y < 3; y++) { // inner loop (y loop)

65. System.out.println("x = " + x + " and y = " + y);

66. if (x == y) { // same conditional expression

67. System.out.println("Break out of both loops.\n");

68. break outer; // new break statement with label

69. }

70. }

71. }

72. }

}

73.Save the class by clicking the disk icon or selecting File, then Save.

74.Run the application by clicking the green play icon or selecting Run, and then Run.

How It Works

Now take a look at how it works.

1. The application begins by executing the main method, which in this case is the only method.

2. The first statement outputs a line of text to the console indicating that the first set of for loops are being executed. They do not include any break statements.

3. The nested for loops iterate through nine times. During each iteration, the current values for x and y are printed to the console. This is how a standard nested for loop iterates: First, in the outer loop, x = 0 and the inner loop will iterate for y = 0, y = 1, and y = 2. When y = 3, the conditional expression on the inner for loop (3 < 3) will evaluate to false, so the inner for loop ends and the outer for loop iterates to x = 1. Again, the inner for loop will iterate for y = 0, y = 1, and y = 2. When y = 3, the conditional expression is false again and the inner loop ends. The outer for loop iterates again to x = 2, and the inner for loop cycles through three values for y again. Finally, when x = 3, the conditional expression on the outer for loop will be evaluated as false and both for loops will end. You can see each of these iterations printed to the console.

4. Another statement is then printed to the console, indicating that the second set of for loops will be executed with a break statement. The program proceeds to the next nested for loops.

5. The second set of nested for loops iterates through only six times. During each iteration, the current values for x and y are printed to the console. When the break statement is encountered, another line is output to the console indicating the break. This is how nested for loops with a break statement iterate: First, in the outer loop x = 0 and in the inner loop y = 0. These values are printed to the console and then the program checks if x equals y. Since 0 == 0 is true, there is a line printed to the console and the break occurs. This breaks from the inner loop and proceeds to the next outer loop iteration. In the outer loop x = 1 and in the inner loop y = 0 again; these are printed to the console. The program again determines if x and y are equal, and because 0 == 1 is false, the inner loop iterates to y = 1 and the values are printed to the console again. Checking again if x equals y, 1 == 1 is now true, so the print statement and break occur a second time. This breaks from the inner loop and proceeds to the next outer loop iteration. This time, in the outer loop x = 2 and in the inner loop y = 0. The inner loop will iterate from y = 0 to y = 1 to y = 2, printing the values each time. At this point, x == y or 2 == 2 is true and the break occurs again. When the outer loop iterates to x = 3, the conditional statement x < 3 becomes false and the outer loop is ended. You can see all of these iterations and breaks printed to the console.

6. Another statement is then printed to the console, indicating that the third set of for loops will be executed with a break statement and label. The program proceeds to the next set of nested for loops.

7. The third set of nested for loops iterates through only once. During the iteration, the current values for x and y are printed to the console. When the break statement is encountered, another line is output to the console indicating the break. This is how nested for loops with a break statement and label iterate: First, in the outer loop x = 0 and in the inner loop y = 0. These values are printed to the console in the first iteration. Then the program checks if x and y are equal and evaluates 0 == 0 as true. Therefore, a line is output to the console indicating a break will occur and the break with label is executed. The program will link the break outer; statement with the outer: label, and both the inner and outer for loops will be broken. The program then proceeds to the end of the main method, which has no further statements to execute, so the program terminates.

Reviewing Control Structures

By now, I hope you have a basic understanding of the most common structures you can use to control the flow of your program. This chapter covered control operators, if-then statements, for loops, while loops, switches, and keywords that can be used for control.

Recall that Java, like most other programming languages, includes operators, which are based on mathematical concepts and used to compare values. With Boolean operators, Java offers the double symbols && and || in addition to the single symbols & and |. These double symbols offer short circuiting to prevent certain types of errors from occurring. It’s advisable to make use of && for AND and || for OR in Boolean logic.

The if-then statement is a basic control structure that simply tests a condition, and if it’s true, executes some statements. It can be expanded with else or else if to allow for executing different statements based on various conditions. Switches operate as sort of a special kind of if-then statement. A single variable is considered, and its value is matched to cases. If they match, then some statements will be executed. You read about how to decide between if-then statements and switches.

Both for and while loops are structures that allow repetition or iteration of some statements. Because they use different syntax, they are each more or less suitable in different circumstances. You read about some considerations to make when choosing the loop structure for a particular problem. Enhanced for loops allow for automatic iteration over iterable objects like arrays. On the other hand, do while loops offer an alternative syntax to while loops and can allow the first iteration to occur before testing the condition.

Finally, you looked at some keywords and how they can also be used to control the flow of a program. Any method will be interrupted and exited when the return keyword is encountered. In this way, you can influence how much of a method is evaluated and executed. The break keyword, with and without a label, can also control how loops and other structures are evaluated by exiting a loop immediately. The continue keyword works similarly, but by jumping to the next iteration of a loop.

Because these structures are so common, they will be used throughout the remainder of this book. This will give you a chance to continue practicing, but it also means it’s important that you feel comfortable with the ideas in this chapter before continuing. If you can follow the execution of the programs from the Try It Out and How It Works exercises, you’re probably ready to move on to the later chapters.