Control Flow
Goals
- Understand conditional statements.
- Understand loops.
Concepts
- control flow
- spaghetti code
- structured programming
Language
if(…) … else …
switch(…) …
break
continue
do … while(…)
while(…) …
for(…; …; …) …
for( : ) …
assert
Lesson
The programs you've seen up till now have been one-shot applications that go straight through, from beginning to end, with no detours. But what if some of the programming commands are optional? What if you want to repeat a command 100 times without retyping it? You'll need to learn about conditional statements and loops, which govern the control flow of your program. The word “control flow” refers to the “flow of control”, or how control passes from one part of the program to the next.
Decisions
if(…) … else …
The most basic conditional statement is if() …
, which says, if some condition is true, then do such-and-such
.
If the condition is not true, nothing happens, unless you include the optional else …
part of the statement.
Java does not have an elseif
statement, but if you put another if(…)
in the body of the else
, it functions the same. This is the only place where leaving off the braces of an else
statement is acceptable. Do you see how the second if(…)
statement is part of the first else
statement? How might you reformat this to show the relationship between the else
and the second if(…)
? The code is completely acceptable as shown, however.
switch(…) …
An if(…)
statement now and then works well, but sometimes you have a lot of decisions to make about the same variable or expression.
This can quickly get messy—and inefficient. Java has to make decision after decision, evaluating the same expression over and over. A better approach is to use the switch(…)
statement, allowing Java to check the expression once and then, using an internal lookup table, quickly go to the correct decision branch in the code. The switch(…)
statement always worked with numeric types, and in later versions of Java it works with type String
as well. But note that the switch(…)
statement only works if you are comparing number or strings for equality. For any other types of expressions, you have to go back to the trusty if(…)
statement.
Loops
If you need to perform some operation multiple times, you could type it in the source code multiple times (or copy and paste). Or you could use one of Java's loop statements. If you need the operation to perform just a little differently each time, use a variable and change it as needed in the loop.
Loops come with a check, either before or at the end, to make sure the loop does not go on forever (unless you want it to). This check functions similar to an if(…)
statement. If you need more checks during the loop operation, just add an if(…)
statement as needed; if you decide to exit the loop, use a break
statement (see below).
do … while(…)
The do ... while(…)
loop has a condition at the end. If the condition evaluates to true
, the loop repeats at the top until it reaches the end, and then it checks the condition again. This continues until the condition evaluates to false
.
The following example adds up the counting numbers until the sum reaches or exceeds the limit
. Then it prints how many counting numbers it took to reach that sum.
while(…) …
A while(…) …
statement functions exactly like a do … while(…)
statement, except that evaluation of the exit expression occurs before executing the loop body. In fact it might be better named the while(…) do …
statement, except that this statement doesn't actually contain the keyword do
.
The following algorithm is one way to add up all the numbers in an array of int
values:
When you become more comfortable with Java, you will probably prefer to combine some of the statements in the body to make the loop more compact:
We can use a while(…) …
loop to improve the Winning Number solution above. We can add the current number to the sum and check it before even incrementing the number. This way the number will never advance if we have reached the limit, obviating the need to subtract one from the solution.
for(…; …; …) …
The for(…; …; …) …
statement, commonly referred to as a “for
loop”, could be considered a form of “syntactic sugar”: it doesn't add any functionality you couldn't do with a while(…)
statement, it just makes setting up the loop much easier. Look again at the Compact Array Sum Using while(…)
code snippet above; you'll note that it has three basic sections:
- Variable initialization:
int index =0
- Loop expression:
index < array.length
- Expression variable update:
index++
A for
loop is essentially a statement that allows you to combine these three components in a compact way. Here is the Compact Array Sum Using while(…)
program again, using a for
loop instead of a while(…)
statement. Even though the three components of the for
loop are presented together on the same line, Java will invoke the components at the correct time, in the same order as in a while(…)
statement. That is, the variable initialization occurs once before the loop begins; the loop expression is evaluated at the beginning of the loop each time, and the expression variable is updated at the end of the loop each time (but only if the expression evaluated to true
—that is, only if the loop wasn't exited).
for( : ) …
Recent versions of Java have added an “enhanced for
loop” that takes the form for( : ) …
. The enhanced for
loop does not contain three sections to allow for a loop counter. Instead the developer does not need to worry about a loop counter at all, and instead provides the variable that will iterate through the values, and the array containing the values over which to iterate. Compare the following to the Array Sum Using while(…)
snippet above.
By dispensing with a loop counter in your program, the enhanced for
loop greatly reduces the risk of errors. A developer has to ensure that a loop counter is initialized correctly, that it is checked correctly at the correct location in the loop, and that it is incremented correctly at the right place. The last point is especially noteworthy, as almost every programmer will probably forget to increment a loop variable at least once at some point in his or her career. What would happen if you were to forget to increment a loop variable in a traditional loop?
Just as important, the enhanced for
loop brings meaning to the variables in the loop. Rather than simply being an almost faceless placeholder, the variable in an enhanced for
loop represents the thing that is being iterated in the array. You accordingly can and should provide a meaningful name to the iterating variable in the enhanced for
loop.
break
The break
statement, which you used already with switch(…)
, will exit a loop block just as it does with a switch(…)
block. The following example shows how we might exit a loop if the sum were to be larger than some maximum threshold.
continue
The continue
statement will also skip the rest of the loop, but instead of exiting the loop like break
, continue
will continue back at the top of the loop for the next cycle. Here is how we could use continue
to skip over even numbers.
Review
Gotchas
- Don't put any “side effects” in an
assert
expression, because they won't be executed if assertions are turned off. - Make sure you didn't leave out a
break
at the end of acase
in aswitch(…)
statement, or you could end up with some unintended results! - When you have a loop the expression of which depends on the value of some variable (such as a counter), make sure you remember to update the the variable inside the loop. If the variable never changes, your loop will never ends! No programmer, not even an expert one, is immune to this mistake, so watch for it.
In the Real World
- Modern best practice is to use braces for the body of an
if(…)
statement (except when creatingelse if
) , even if the body consists of a single statement, because the lack of braces can be very confusing—to the developer, not to the compiler. The same goes for the other decision and loop statements that allow a body consisting of a single statement. - Liberally use the
assert
statement to check assumptions about your calculations as you go along. - If your
switch(…)
statement purports to exhaust all possibilities, include adefault
section withassert
to ensure that an error is generated if for some reason you didn't account for some value. - Prefer using an enhanced
for
loop over a traditionalfor
loop, even if you need a counter variable for some reason.
Think About It
- Do I have too many
if(…)
statements checking the equality of the same variable? Maybe aswitch(…)
statement would be more appropriate.
Self Evaluation
- Could you have a statement
if(true) …
? What would that mean? What aboutif(false) …
? What would happen? - What effect would
while(true) …
have? - Why is a
while(…) …
loop sometimes safer or more appropriate than ado … while(…)
loop? - Is it guaranteed that the third component of a
for(…; …; …) …
statement will execute? Why or why not? - In what situation might you use a nested loop (that is, one loop inside another)? If you are using loops with counter variables, what might you name them?
- Why is an enhanced
for
loop considered safer than a traditionalfor
loop? Is an enhancedfor
loop safer than a traditionalfor
loop even if you need a counter variable?
Task
Create a program named “Booker” to print a list of the best-selling single-volume books with more than 100 million copies sold according to Wikipedia on 2015-08-26.
- Name the application class
Booker
, and place it in abooker
subpackage.- Continue using the same base package for a domain name you own or have control over.
- Make sure you choose a good package name, as you will continue to use it throughout the course.
- Provide a Maven build configuration for the program
- Use the same
groupId
as your base package name. - Use
booker
as theartifactId
. - Use the lesson number as the project
version
. For each of the future lessons, update this version number appropriately. As a best practice you should a-SNAPSHOT
version during development, and switch to a release version only when you submit your homework.
- Use the same
- In your output include the book names, authors, original language, year published, and approximate sales. Include all titles in their original languages, even if you also provide a translation.
- Use arrays to represent the book information in your code. Use as many arrays of as many types as you need, but do not use Java classes for this purpose; you will learn about them in a future lesson.
Send your entire project to your teacher as a single, compressed archive.
See Also
- Control Flow Statements (Oracle - The Java™ Tutorials)
- The if-then and if-then-else Statements (Oracle - The Java™ Tutorials)
- The switch Statement (Oracle - The Java™ Tutorials)
- The while and do-while Statements (Oracle - The Java™ Tutorials)
- The for Statement (Oracle - The Java™ Tutorials)
- Branching Statements (Oracle - The Java™ Tutorials)