(syllabus and calendar)Ch. 3 Program Control Statements |
Session 3switch - case, default
MIN_VAL and MAX_VAL of Integer |
Computers are useful because we can harness their speed (particulary in loops of many iterations), and rely on their consistent behavior in program control statements. Unlike human beings, they do not get tired, bored, go on strike, form their own opinions, lose their focus on the task at hand, or make errors unless it is our fault. If computers are like a fast vehicle, control statements are the steering wheel. Computers are like good soldiers that do exactly as instructed, but we, the Generals, have to give them clear, logical, complete orders. In this sense, we direct the power of the computer through control statements.
The most basic control statement is the if test.
The syntax involves a
check that the if expression evaluates to a Boolean
true (or at least does not return
false):
if(condition) statement;
int myNum1 = 2;
int myNum2 = 4;
if (myNum1 + myNum1 == myNum2); // returns true
What is the difference between (a) and (b)?
(a) if (isLeapYear == true)
(b) if (isLeapYear)
Answer: (a) is redundant because the statement after the condition only executes if the condition evaluates to true. It is better to write (b).
The three statements below are equivalent to each other.
if(n==1) return 1; // one-line if statement - quickest to write.
// 2-line if statement is the most bug-prone if not read with care. if(n==1) return 1;
// 4-line simple if statement - this is the most clear and I prefer it. if(n==1) { return 1; }
which means three syntactic forms are possible:
if(condition) statement;
if(condition) statement;
if(condition) { statement; }
if(booleanExpression) // do
something
else if(booleanExpression) // do something
...
else(booleanExpression) // do something
More complex logic can be implemented in a ladder or sequence: if, else if, else if, else if, else sequence. There can be any number of else if statements. The beginning statement is if and the final statement is else.
Another example:
Compare the ElseIfDemo above with the switch version below:
The series of else if statements becomes awkward if it is long. A more elegant and concise way to express the same logic is the switch with a series of case statements within a switch.
switch(valueToTest)
{
case (specificValue) : // do something
break;
...
default: // do something
Top summarize, typically a switch has a series of case statements and at least one break statement, and often a default value.
Here we combine Scanner and a switch, and each case tests the value of the String:
By the way, the program above calls a method of the String class to convert the String to lower case. This program also defines and calls a custom method.
It is difficult to think of a use case that never uses the keyword break.
You can group adjacent case values, and here it can make sense to omit break for some adjacent values. Because the test is of a specific value and booleans are not allowed, you cannot specify if i < 3.
Control statements (if, loop, case in switch) permit nesting.
Loops are the core of a software "engine". Loops allow you to take advantage of the primary strength of the computer, SPEED, tireless speed, even to point of willingness to do infinite loops, like Sisyphus, but without complaint.
The most straightforward loop syntax is that of the while loop, which has three distinct expressions located exactly where they occur in the sequence of execution.
Two disadvantages of the while loop syntax:
The most common loop is a for loop. The syntax combines the three statements of the while loop into a single, three-expression line:
for(initialization; condition; increment) statement;
The increment operation occurs after the final line within the code block and before re-entry into the next iteration. In this sense, a for loop is equivalent to a while loop.
Example:
The output of the while loop and the for loop is the same:
Looping with char to process the letters of the alphabet
The following is a loop to process the array of command-line arguments.
java WhileLoopForArgs one two three four
one
two
three
four
Let's convert this while loop to a for loop.
The for loop is a convenient way of placing the initialization, test, and increment expressions of the while loop within a single line.
Notes:
for loop, while loop | do while loop | |
1. | initialize | initialize |
2. | test | increment |
execute the code block | ||
3. | increment | test |
A do while loop always executes at least once because it checks its condition after the executing an iteration of the statements it contains. Consider GuessTheCharacterWithScanner.java.
To review the object-oriented necessity of an object existing before we can call its methods, see the TimerDemo.java example in the zip.
The program is also a preview to Week 5, when we will look more closely at the String class.
The main method uses the main thread. Many programs spawn additional threads to enable multi-taskking. For example, a Word processing application might start a new thread to spool a print job at the same time you are running a spelling checker thread.
The output is similar to:
Computers are stupid but fast ...
0
1
2
3
4
5
I'll take it slow for a while ...
1.499519212
6
I'll take it slow for a while ...
1.509321925
7
I'll take it slow for a while ...
1.512039659
8
I'll take it slow for a while ...
1.512053348
9
Back to full speed ...
11
12
13
14
15
16
17
18
19
20
21
22
For details about the sleep method, see http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#sleep%28long%29
Sometimes it's necessary to initialize several variables before beginning a for loop. Similarly you may want to increment more than one variable. Java lets you do this by placing a comma between the different initializers and incrementers:
for (int i = 1, j = 100; i < 100; i = i+1, j = j-1) {
System.out.println(i + j);
}
You can't, however, include multiple test conditions, at least not with commas. The following line is illegal and will generate a compiler error.
for (int i = 1, j = 100; i <= 100, j > 0; i = i-1, j = j-1) {
To include multiple tests, use one or more the logical operators. This means that the condition can be simple or complex, yet still evaluate to a single boolean value.
for (initialization; condition; increment) statement;
Another example of using a logical operator to enrich the conditional test, this time in an if
statement.
An infinite loop is one in which the condition never evaluates to a boolean false. The crudest way to do this, is to hard-code the value true.
But a more elegant way is to leave the condition blank, such that is never can return false. (This short-cut for convenience might seem to run counter to the general philosophy of the explicit declarations of a strongly-typed language, but the condition is always implicit about its type, and only optional in regard to the value being explicit or implicit. We never formally declare the type of the condition as boolean.)
Does the integer data type, like the byte data type, OVERFLOW and UNDERFLOW after it reaches its upper and lower boundary?
Yes, it does overflow and underflow:
The shortest, clearest way to write an infinite loop is:
for( ; ; )
What is different now?
Why doe this application fail to compile?
What does the error message mean?
InfiniteLoop2.java:9: unreachable statement
System.out.println(); // Finish the line
What are typical use cases for an infinite loop?
The answer is embedded systems or daemon services, such as:
Infinite loop that tests for a particular character. In this case, we use the infinite loop instead of a do while loop.
The break keyword causes execution to exit the current code block, such as the current iteration of a loop. The keyword can be on the same line, the next line, or within its own code block.
Both break and continue interrupt the "normal" flow of execution. Whereas break forces the loop to exit completely, continue forces the loop to attempt to re-enter immediately at the next iteration, that is, to re-interate without completing whatever remains in the current iteration.
The following example illustrates a valid use case: counting the occurrences
of a letter. Here continue prevents incorrect
counting of the letter in question.
Using break with a nested loop.
This for loop uses a double instead of an integer (which is unusual). Note that num++ involves a compound assignment operator and is equivalent to writing num = num + 1;
The loop decrements instead of incrementing, again with a compound assignment operator.
Monitoring two counters in a for loop
Java syntax allows a loop to have and empty body yet still do something due to the three expressions of the control itself:
A Help system with an infinite loop
A lot of work done with only a few lines of code.
Let's rewrite this while loop as a for loop.
Use a while loop nested inside a for loop
Nested loops are risky because of circular logic. For example, the do-while can limit the number of tries to 5. If we insert a nested for loop inside the do-while, the circularity of the logic causes unnecessary repetitions.
There is a class that corresponds to the primitive int data type: java.lang.Integer. This class has fields that represent the maximum and minimum values of the data type.