Chapter 4 Making Decisions Flashcards

1
Q

Making Decisions

A

Using Operators and Decision Constructs
* Use Java control statements including if, if/else, switch
* Create and use do/while, while, for and for each loops, including nested loops, use break and continue statements

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

STATEMENTS AND BLOCKS

A

a Java statement is a complete unit of execution in Java, terminated with a semicolon (;).

a block of code in Java is a group of zero or more statements between balanced braces ({}) and can be used anywhere a single statement is allowed.

// Single statement
patrons++;

// Statement inside a block
{
patrons++;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Block

A

a block of code in Java is a group of zero or more statements between balanced braces ({}) and can be used anywhere a single statement is allowed.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Java control flow statements.

A

Java control flow statements.
Control flow statements break up the flow of execution by using decision-making, looping, and branching, allowing the application to selectively execute particular segments of code.

A statement or block often functions as the target of a decision-making statement.

the target of a decision-making statement can be a single statement or block of statements.

// Single statement
if(ticketsTaken > 1)
   patrons++;

// Statement inside a block
if(ticketsTaken > 1)
{
    patrons++;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q
// Single statement
if(ticketsTaken > 1)
   patrons++;

// Statement inside a block
if(ticketsTaken > 1)
{
    patrons++;
}
A

Note: both of the previous examples are equivalent, stylistically the second form is often preferred, even if the block has only one statement. The second form has the advantage that you can quickly insert new lines of code into the block, without modifying the surrounding structure. While either of these forms is correct, it might explain why you often see developers who always use blocks with all decision- making statements.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

THE IF STATEMENT

A
if (boolean expression) {
     // Branch if true
}
  1. if keyword
  2. Parentheses required for boolean expression
  3. curly braces required for block of multiple statemnts, optional for single statement

Note: it is often considered good coding practice to put blocks around the execution component of if statements, as well as many other control flow statements, although it is certainly not required.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

WATCH INDENTATION AND BRACES

A
if(hourOfDay < 11)
    System.out.println("Good Morning");
    morningGreetingCount++; //will always execute

morningGreetingCount will always execute the increment operation.

Note: Remember that in Java, unlike some other programming languages, tabs are just whitespace and are not evaluated as part of the execution. When you see a control flow statement in a question, be sure to trace the open and close braces of the block, ignoring any indentation you may come across.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

THE ELSE STATEMENT

A
if (boolean expression) {
    // Branch if true
} else {
    // Branch if false
}
  1. if keyword
  2. Parentheses required for boolean expression
  3. curly braces required for block of multiple statemnts, optional for single statement
  4. optional else statement
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

else if

A
if(hourOfDay < 11) {
    System.out.println("Good Morning");
} else if(hourOfDay < 15) {
    System.out.println("Good Afternoon");
} else {
    System.out.println("Good Evening");
}

If neither of the first two expressions is true, it will execute the final code of the else block.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q
A
if(hourOfDay < 15) {
    System.out.println("Good Afternoon");
} else if(hourOfDay < 11) {
    System.out.println("Good Morning"); // COMPILES BUT IS UNREACHABLE
} else {
    System.out.println("Good Evening");
}

One thing to keep in mind in creating complex if and else statements is that order is important.

If a value is less than 11, then it must be also less than 15 by definition.

Therefore, if the second branch in the example can be reached, the first branch can also be reached. Since execution of each branch is mutually exclusive in this example (that is, only one branch can be executed), then if the first branch is executed, the second cannot be executed.

Therefore, there is no way the second branch will ever be executed, and the code is deemed unreachable.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

VERIFYING THAT THE IF STATEMENT EVALUATES TO A BOOLEAN EXPRESSION

A

the boolean expression inside the if statement is not actually a boolean expression.
ex:

int hourOfDay = 1;
if(hourOfDay) { // DOES NOT COMPILE
...
}

ex:

int hourOfDay = 1;
if(hourOfDay = 5) { // DOES NOT COMPILE
...
}

Note: in Java, where 0 and 1 are not considered boolean values.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

THE SWITCH STATEMENT

A

switch statement is a complex decision-making structure in which a single value is evaluated and flow is redirected to the first matching branch, known as a case statement. If no such case statement is found that matches the value, an optional default statement will be called. If no such default option is available, the entire switch statement will be skipped.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q
switch (variableToTest) {
    case constantExpression1:
        // Branch for case1;
        break;

    case constantExpression2:
         // Branch for case2;
         break;

...

    default:
        // Branch for default
}
A
  1. switch keyword required
  2. parentheses (required) for variable to test (a switch statement has a target variable that is not evaluated until runtime.)
  3. begining curly brace (required)
  4. switch statement may contain 0 or more case branches
  5. case keyword is required
  6. Optional break
  7. Optional default that may appear anywhere within switch statement
  8. ending curly brace (required)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Proper Switch Syntax

A

https://github.com/zero14c/OCP-Notes/blob/main/images/structure%20of%20switch%20statement.PNG?raw=true

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q
int month = 5;
switch month { // DOES NOT COMPILE
case 1: System.out.print("January");
}
A

does not compile because it is missing parentheses around the switch variable.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q
int month = 5;
switch (month) // DOES NOT COMPILE
case 1: System.out.print("January");
A

does not compile because it is missing braces around the switch body.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
17
Q
int month = 5;

switch (month) {
case 1: 2: System.out.print("January"); // DOES NOT COMPILE
}
A

does not compile because the case keyword is missing before the 2: label.
Each case statement requires the keyword case, followed by a value and a colon (:).

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
18
Q
int month = 5;

switch (month) {
case 1 || 2: System.out.print("January"); // DOES NOT COMPILE
}
A

does not compile because 1 || 2 uses the short-circuit boolean operator, which cannot be applied to numeric values.

A single bitwise operator (|) would have allowed the code to compile, although the interpretation of this might not be what you expect. It would then only match a value of month that is the bitwise result of 1 | 2, which is 3, and would not match month having a value 1 or 2. You don’t need to know bitwise arithmetic for the exam, but you do need to know proper syntax for case statements.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
19
Q
A

combine case statements in ways that are not valid.

One last note you should be aware of for the exam: a switch statement is not required to contain any case statements.
For example, this statement is perfectly valid:

switch (month) {}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
20
Q

Switch Data Types

A

a switch statement has a target variable that is not evaluated until runtime.

Prior to Java 5.0, this variable could only be int values or those values that could be promoted to int, specifically byte, short, char, or int, which we refer to as primitive numeric types.

The switch statement also supports any of the wrapper class versions of these primitive numeric types, such as Byte, Short, Character, or Integer.

Notice that boolean, long, float, and double are excluded from switch statements, as are their associated Boolean, Long, Float, and Double classes.

The reasons are varied, such as boolean having too small a range of values and floating-point numbers having quite a wide range of values. For the exam, though, you just need to know that they are not permitted in switch statements.

When enumeration, denoted enum, was added in Java 5.0, support was added to switch statements to support enum values.

An enumeration is a fixed set of constant values, which can also include methods and class variables, similar to a class definition.

For the exam, you do not need to know how to create enums, but you should be aware they can be used as the target of switch statements.

In Java 7, switch statements were further updated to allow matching on String values.

In Java 10, if the type a var resolves to is one of the types supported by a switch statement, then var can be used in a switch statement too.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
21
Q

SWITCH HISTORY AND CHANGES

A

Java 12 launched with a Preview release of a
powerful new feature called Switch Expressions, a construct that combines switch statements with lambda expressions and allows switch statements to return a value. You won’t need to know Switch Expressions
for the exam

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
22
Q

list of all data types supported by switch statements:

A

● int and Integer
● byte and Byte
● short and Short
● char and Character
● String
● enum values
● var (if the type resolves to one of the preceding types)

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
23
Q

For the exam, we recommend you memorize this list.
Remember, boolean, long, float, double, and each of their associated wrapper classes are not supported by switch statements.

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
24
Q

Switch Control Flow

int dayOfWeek = 5;
switch(dayOfWeek) {
default:
System.out.println("Weekday");
break;
case 0:
System.out.println("Sunday");
break;
case 6:
System.out.println("Saturday");
break;
}
A

With a value of dayOfWeek of 5, this code will output the following:

Weekday

The first thing you may notice is that there is a break statement at the end of each case and default section. We’ll discuss break statements in more detail when we discuss branching, but for now all you need to know is that they terminate the switch statement and return flow control to the enclosing statement. As you’ll soon see, if you leave out the break statement, flow will continue to the next proceeding case or default block automatically.

Another thing you might notice is that the default block is not at the end f the switch statement. There is no requirement that the case or default statement be in a particular order, unless you are going to have pathways that reach multiple sections of the switch block in a single execution.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
25
Q

Switch Control Flow

var dayOfWeek = 5;
switch(dayOfWeek) {
case 0:
System.out.println("Sunday");
default:
System.out.println("Weekday");
case 6:
System.out.println("Saturday");
break;
}
A

This code looks a lot like the previous example. Notice that we used a var for the switch variable, which is allowed because it resolves to an int by the compiler. Next, two of the break statements have been removed, and the order has been changed. This means that for the given value of dayOfWeek, 5, the code will jump to the default block and then execute all of the proceeding case statements in order until it finds a break statement or finishes the switch statement:

**Weekday
Saturday
**
The order of the case and default statements is now important since
placing the default statement at the end of the switch statement would cause only one word to be output.

What if the value of dayOfWeek was 6 in this example? Would the
default block still be executed? The output of this example with
dayOfWeek set to 6 would be as follows:

Saturday

Even though the default block was before the case block, only the case block was executed. If you recall the definition of the default block, it is branched to only if there is no matching case value for the switch statement, regardless of its position within the switch statement. Finally, if the value of dayOfWeek was 0, all three statements would be output:
**Sunday
Weekday
Saturday
**
Notice that in this last example, the default statement is executed since there was no break statement at the end of the preceding case block. While the code will not branch to the default statement if there is a matching case value within the switch statement, it will execute the default statement if it encounters it after a case statement for which there is no terminating break statement.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
26
Q

The exam creators are fond of switch examples that are missing break statements!
When evaluating switch statements on the exam, always consider that multiple branches may be visited in a single execution.

A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
27
Q

Acceptable Case Values

A

First off, the values in each case statement must be compile-time constant values of the same data type as the switch value.

This means you can use only literals, enum constants, or final constant variables of the same data type.

By final constant, we mean that the variable must be marked with the final modifier and initialized with a literal value in the same expression in which it is declared.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
28
Q
final int getCookies() { return 4; }
void feedAnimals() {
    final int bananas = 1;
    int apples = 2;
    int numberOfAnimals = 3;
    final int cookies = getCookies();
    switch (numberOfAnimals) {
        case bananas:
        case apples: // DOES NOT COMPILES
        case getCookies(): // DOES NOT COMPILE
        case cookies : // DOES NOT COMPILE
        case 3 * 5 :
    }
}
A

The bananas variable is marked final, and its value is known at compile-time, so it is valid.

The apples variable is not marked final, even though its value is known, so it is not permitted.

The next two case statements, with values getCookies() and cookies, do not compile because methods are not evaluated until runtime, so they cannot be used as the value of a case statement, even if one of the values is stored in a final variable.

The last case statement, with value 3 * 5, does compile, as expressions are allowed as case values, provided the value can be resolved at compile-time.

They also must be able to fit in the switch data type without an explicit cast. We’ll go into that in more detail shortly.

Next, the data type for case statements must all match the data type of the switch variable.

For example, you can’t have a case statement of type String, if the switch statement variable is of type int, since the types are incomparable.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
29
Q
private int getSortOrder(String firstName, final String lastName) {
    String middleName = "Patricia";
    final String suffix = "JR";
    int id = 0;
    switch(firstName) {
        case "Test":
            return 52;
        case middleName: // DOES NOT COMPILE
            id = 5;
            break;
        case suffix:
            id = 0;
            break;
        case lastName: // DOES NOT COMPILE
            id = 8;
            break;
        case 5: // DOES NOT COMPILE
            id = 7;
            break;
        case 'J': // DOES NOT COMPILE
            id = 10;
            break;
        case java.time.DayOfWeek.SUNDAY: // DOES NOT COMPILE
            id=15;
            break;
        }
    return id;
}
A

The first case statement, “Test”, compiles without issue since it is a String literal and is a good example of how a return statement, like a break statement, can be used to exit the switch statement early.

The second case statement does not compile because middleName is not a constant value, despite having a known value at this particular line of execution. If a final modifier was added to the declaration of middleName, this case statement would have compiled.

The third case statement compiles without issue because suffix is a final constant variable.

In the fourth case statement, despite lastName being final, it is not constant as it is passed to the function; therefore, this line does not compile as well.

Finally, the last three case statements do not compile because none of them has a matching type of String, the last one being an enum value.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
30
Q

Numeric Promotion and Casting
~~~
short size = 4;
final int small = 15;
final int big = 1_000_000;
switch(size) {
case small:
case 1+2 :
case big: // DOES NOT COMPILE
}
~~~

A

switch statements support numeric promotion that
does not require an explicit cast.

As you may recall from our discussion of numeric promotion and casting in Chapter 3, the compiler can easily cast small from int to short at compile-time because the value 15 is small enough to fit inside a short.

This would not be permitted if small was not a compile-time constant.

Likewise, it can convert the expression 1+2 from int to short at compile-time. On the other hand, 1_000_000 is too large to fit inside of short without an explicit cast, so the last case statement does not compile.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
31
Q

loop

A

A loop is a repetitive control structure that can execute a statement of code multiple times in succession.

By making use of variables being able to be assigned new values, each repetition of the statement may be different.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
32
Q

while loop

A
int counter = 0;
while (counter < 10) {
    double price = counter * 10;
    System.out.println(price);
    counter++;
}
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
33
Q
A
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
34
Q
A
35
Q

The simplest repetitive control structure in Java is the while statement, described in Figure 4.4. Like all repetition control structures, it has a termination condition, implemented as a boolean expression, that will continue as long as the expression evaluates to true.

A
36
Q
int roomInBelly = 5;
public void eatCheese(int bitesOfCheese) {
    while (bitesOfCheese > 0 && roomInBelly > 0) {
        bitesOfCheese--;
        roomInBelly--;
    }
    System.out.println(bitesOfCheese+" pieces of cheese left");
}
A
37
Q

how many times is Not full! printed in the following example?
~~~
int full = 5;
while(full < 5) {
System.out.println(“Not full!”);
full++;
}
~~~

A

The answer? Zero!

On the first iteration of the loop, the condition is reached, and the loop exits. This is why while loops are often used in places where you expect zero or more executions of the loop. Simply put, the body of the loop may not execute at all or may execute many times.

38
Q

do/while loop

A

do/while loop guarantees that the
statement or block will be executed at least once.

39
Q

while vs do/while loop

A

while loop is executed zero or more times, a do/while loop is executed one or more times.

40
Q

do/while example

A
int lizard = 0;
do {
lizard++;
} while(false);
System.out.println(lizard); // 1

do/while loop purposely orders the body before the conditional expression so that the body will be executed at least once.

Java will execute the statement block first and then check the loop condition. Even though the loop exits right away, the statement block is still executed once, and the program prints 1.

41
Q

COMPARING WHILE AND DO/WHILE LOOPS

A
42
Q

INFINITE LOOPS

A

The single most important thing you should be aware of when you are using any repetition control structure is to make sure they always terminate!
Failure to terminate a loop can lead to numerous problems in practice including overflow exceptions, memory leaks, slow performance, and even bad data.

43
Q

INFINITE LOOPS

int pen = 2;
int pigs = 5;
while(pen < 10)
pigs++;
A

The variable pen is never modified, so the expression (pen < 10) will always evaluate to true. The result is that the loop will never end, creating what is commonly referred to as an infinite loop. An infinite loop is a loop whose termination condition is never reached during runtime.

44
Q

A PRACTICAL USE OF AN INFINITE LOOP

A

In practice, infinite loops can be used to monitor processes that exist for the life of the program—for example, a process that wakes up every 30 seconds
to look for work to be done and then goes back to sleep afterward.

When creating an infinite loop like this, you need to make sure there are only a fixed number of them created by the application, or you could run out of memory. You also have to make sure that there is a way to stop them, often as part of the application shutting down. Finally, there are modern alternatives to creating infinite loops, such as using a scheduled thread executor, that are well beyond the scope of the exam.

If you’re not familiar with how to create and execute multiple processes at once, don’t worry, you don’t need to be for this exam. When you continue on to exam 1Z0-816, you will study these topics as part of concurrency.

45
Q

Constructing for Loops

A
  1. basic for loop
  2. enhanced for loop, for-each loop
46
Q

for loop structure

A

A basic for loop has the same conditional boolean expression and statement, or block of statements, as the while loops, as well as two new sections: an initialization block and an update statement.

47
Q
for(int i=0; i < 10; i++)
    System.out.print("Value is: "+i);
System.out.println(i); // DOES NOT COMPILE
A

code does not compile because the loop variable i is referenced outside the loop

48
Q

For the exam, you are going to have to know how to read forward and backward for loops. When you see a for loop on the exam, pay close attention to the loop variable and operations if the decrement operator, –, is used. While incrementing from 0 in a for loop is often straightforward,
decrementing tends to be less intuitive. In fact, if you do see a for loop with a decrement operator on the exam, you should assume they are trying to test your knowledge of loop operations.

A
49
Q

for loop variations likely to be seen on the exam.

A
  1. Creating an Infinite Loop
    ~~~
    for( ; ; )
    System.out.println(“Hello World”);
    ~~~
    Although this for loop may look like it does not compile, it will in fact compile and run without issue. It is actually an infinite loop that will print the same statement repeatedly. This example reinforces the fact that the components of the for loop are each optional. Note that the semicolons separating the three sections are required, as for( ) without any semicolons will not compile.
  2. Adding Multiple Terms to the for Statement
int x = 0;
for(long y = 0, z = 4; x < 5 && y < 10; x++, y++) {
    System.out.print(y + " "); 
}
System.out.print(x + " ");

This code demonstrates three variations of the for loop you may not have seen.

First, you can declare a variable, such as x in this example, before the loop begins and use it after it completes.

Second, your initialization block, boolean expression, and update statements can include extra variables that may or may not reference each other. For example, z is defined in the initialization block and is never used.

Finally, the update statement can modify multiple variables.

This code will print the following when executed:
0 1 2 3 4 5

  1. Redeclaring a Variable in the Initialization Block
int x = 0;
for(int x = 4; x < 5; x++) { // DOES NOT COMPILE
System.out.print(x + " ");
}

This example looks similar to the previous one, but it does not compile because of the initialization block. The difference is that x is repeated in the initialization block after already being declared before the loop, resulting in
the compiler stopping because of a duplicate variable declaration. We can fix this loop by removing the declaration of x from the for loop as follows:

int x = 0;
for(x = 0; x < 5; x++) {
    System.out.print(x + " ");
}

Note that this variation will now compile because the initialization block simply assigns a value to x and does not declare it.

  1. Using Incompatible Data Types in the Initialization Block
int x = 0;
for(long y = 0, int z = 4; x < 5; x++) { // DOES NOT COMPILE
    System.out.print(y + " ");
}

Like the third example, this code will not compile, although this time for a different reason. The variables in the initialization block must all be of the same type. In the multiple terms example, y and z were both long, so the
code compiled without issue, but in this example they have differing types, so the code will not compile.

  1. Using Loop Variables Outside the Loop
for(long y = 0, x = 4; x < 5 && y < 10; x++, y++) {
    System.out.print(y + " ");
}
System.out.print(x); // DOES NOT COMPILE

We covered this already at the start of this section, but this is so important for passing the exam that we discuss it again here. If you notice, x is defined in the initialization block of the loop and then used after the loop terminates. Since x was only scoped for the loop, using it outside the loop will cause a compiler error.

50
Q

Modifying Loop Variables
~~~
for(int i=0; i<10; i++)
i = 0;
for(int j=1; j<10; j++)
j–;
for(int k=0; k<10; )
k++;
~~~

A

All three of these examples compile, as Java does let you modify loop variables, whether they be in for, while, or do/while loops.

The first two examples create infinite loops, as loop conditions i<10 and j<10 are never reached, independently.

In the first example, i is reset during every loop to 0, then incremented to 1, then reset to 0, and so on.

In the second example, j is decremented to 0, then incremented to 1, then decremented to 0, and so on.

The last example executes the loop exactly 10 times, so it is valid, albeit a little unusual.

Java does allow modification of loop variables, but you should be wary if you see questions on the exam that do this. While it is normally straightforward to look at a for loop and get an idea of how many times the loop will execute, once we start modifying loop variables, the behavior can be extremely erratic. This is especially true when nested loops are involved, which we cover later in this chapter.

51
Q

There are also some special considerations when modifying a Collection object within a loop. For example, if you delete an element from a List while iterating over it, you could run into a ConcurrentModificationException. This topic is out of scope for the exam, though. You’ll revisit this when studying for the 1Z0-816 exam.

A
52
Q

As a general rule, it is considered a poor coding practice to modify loop variables due to the unpredictability of the result. It also tends to make code difficult for other people to read. If you need to exit a loop early or change the flow, you can use break, continue, or return, which we’ll discuss
later in this chapter.

A
53
Q

If you need to exit a loop early or change
the flow, you can use break, continue, or return,

A
54
Q

THE FOR-EACH LOOP

A

the enhanced for loop, or for-each loop as we like to call it. The for-each loop is a specialized structure designed to iterate over arrays and various Collection Framework classes

55
Q

The for-each loop declaration is composed of an initialization section and an object to be iterated over. The right side of the for-each loop must be one of the following:
* A built-in Java array
* An object whose type implements java.lang.Iterable

A
56
Q

array or collection of items, such as a List or a Set. For the exam, you should know that this does not include all of the Collections Framework classes or interfaces, but only those that implement or extend that Collection interface. For example, Map is not supported in a for-each loop, although Map does include methods that return Collection instances.

A
57
Q

The left side of the for-each loop must include a declaration for an instance of a variable whose type is compatible with the type of the array or collection on the right side of the statement. A var may also be used for the
variable type declaration, with the specific type determined by the right side of the for-each statement. On each iteration of the loop, the named variable on the left side of the statement is assigned a new value from the array or collection on the right side of the statement.

A
58
Q
public void printNames(String[] names) {
for(String name : names)
    System.out.println(name);
}
A
59
Q

What will this code output?

final String[] names = new String[3];
names[0] = "Lisa";
names[1] = "Kevin";
names[2] = "Roger";
for(String name : names) {
    System.out.print(name + ", ");
}
A

The code will compile and print the following:
Lisa, Kevin, Roger,

60
Q

What will this code output?

List<String> values = new ArrayList<String>();
values.add("Lisa");
values.add("Kevin");
values.add("Roger");
for(var value : values) {
    System.out.print(value + ", ");
}
A

This code will compile and print the same values:
Lisa, Kevin, Roger,

61
Q
  • Like the regular for loop, the for-each loop also accepts var for the loop variable, with the type implied by the data type being iterated over.
  • When you see a for-each loop on the exam, make sure the right side is an array or Iterable object and the left side has a matching type.
A
62
Q

Why does this fail to compile?

String names = "Lisa";
for(String name : names) { // DOES NOT COMPILE
    System.out.print(name + " ");
}
A

In this example, the String names is not an array, nor does it define a list of items, so the compiler will throw an exception since it does not know how to iterate over the String. As a developer, you could iterate over each character of a String, but this would require using the charAt() method, which is not compatible with a for-each
loop. The charAt() method, along with other String methods, will be covered in Chapter 5.

63
Q

Why does this fail to compile?

String[] names = new String[3];
for(int name : names) { // DOES NOT COMPILE
    System.out.print(name + " ");
}
A

This code will fail to compile because the left side of the for-each statement does not define an instance of String. Notice that in this last example, the array is initialized with three null pointer values. In and of itself, that will not cause the code to not compile, as a corrected loop would just output null three times.

64
Q

Switching Between for and for-each Loops

A

This sample code would output the following:
Lisa, Kevin, Roger
~~~
List<String> names = new ArrayList<String>();
names.add("Lisa");
names.add("Kevin");
names.add("Roger");
for(int i=0; i<names.size(); i++) {
String name = names.get(i);
if(i > 0) {
System.out.print(", ");
}
System.out.print(name);
}
~~~</String></String>

This sample code would output the following:
2, 3,
Notice that we skip the first index of the array, since value[-1] is not defined and would throw an IndexOutOfBoundsException error if called with i=0. When comparing n elements of a list with each other, our loop should be executed n-1 times.

int[] values = new int[3];
values[0] = 1;
values[1] = Integer.valueOf(3);
values[2] = 6;
for(int i=1; i<values.length; i++) {
    System.out.print((values[i]-values[i-1]) + ", ");
}
65
Q

enhanced for-each loops are extremely convenient
in a variety of circumstances. As a developer, though, you can always revert to a standard for loop if you need fine-grained control.

A
66
Q

COMPARING FOR AND FOR-EACH LOOPS

A

how for-each loops are converted to for loops by the compiler.

When for-each was introduced in Java 5, it was added as a compile-time enhancement. This means that Java actually converts the for-each loop into a standard for loop during compilation.

ex:
~~~
for(String name : names) {
System.out.print(name + “, “);
}

for(int i=0; i < names.length; i++) {
String name = names[i];
System.out.print(name + “, “);
}
~~~

For objects that inherit Iterable, there is a different, but similar, conversion. For example, assuming values is an instance of List<Integer>, the following two loops are equivalent:
~~~
for(int value : values) {
System.out.print(value + ", ");
}
for(Iterator<Integer> i = values.iterator(); i.hasNext(); ) {
int value = i.next();
System.out.print(value + ", ");
}
~~~
Notice that in the second version, there is no update statement in the for loop as next() both retrieves the next available value and moves the iterator forward.</Integer></Integer>

67
Q

how for-each loops are converted
to for loops by the compiler.

A

how for-each loops are converted to for loops by the compiler.

When for-each was introduced in Java 5, it was added as a compile-time enhancement. This means that Java actually converts the for-each loop into a standard for loop during compilation.

68
Q

Controlling Flow with Branching

A
69
Q

NESTED LOOPS

A

A nested loop is a loop that contains another loop including while, do/while, for, and for-each loops.

int[][] myComplexArray = {{5,2,1,3},{3,9,8,9},{5,7,12,7}};
for(int[] mySimpleArray : myComplexArray) {
    for(int i=0; i<mySimpleArray.length; i++) {
        System.out.print(mySimpleArray[i]+"\t");
    }
    System.out.println();
}

Notice that we intentionally mix a for and for-each loop in this example. The outer loop will execute a total of three times. Each time the outer loop executes, the inner loop is executed four times. When we execute this code, we see the following output:
5 2 1 3
3 9 8 9
5 7 12 7

70
Q

Nested loops can include while and do/while, as shown in this example.
See whether you can determine what this code will output:
~~~
int hungryHippopotamus = 8;
while(hungryHippopotamus>0) {
do {
hungryHippopotamus -= 2;
} while (hungryHippopotamus>5);
hungryHippopotamus–;
System.out.print(hungryHippopotamus+”, “);
}
~~~

A

The first time this loop executes, the inner loop repeats until the value of hungryHippopotamus is 4. The value will then be decremented to 3, and that will be the output at the end of the first iteration of the outer loop.

On the second iteration of the outer loop, the inner do/while will be executed once, even though hungryHippopotamus is already not greater than 5. As you may recall, do/while statements always execute the body at least once. This will reduce the value to 1, which will be further lowered by the decrement operator in the outer loop to 0. Once the value reaches 0, the outer loop will terminate. The result is that the code will output the following:
3, 0,

The examples in the rest of this section will include many nested loops. You will also encounter nested loops on the exam, so the more practice you have with them, the more prepared you will be.

71
Q

Some of the most time-consuming questions you may see on the exam could involve nested loops with lots of branching. We recommend you try to answer the question right away, but if you start to think it is going to take too long, you should mark it and come back to it later. Remember, all questions on the exam are weighted evenly!

A
72
Q

ADDING OPTIONAL LABELS

A

label is an optional pointer to the head of a statement that allows the application flow to jump to it or break from it. It is a single identifier that is proceeded by a colon (:).

int[][] myComplexArray = {{5,2,1,3},{3,9,8,9},{5,7,12,7}};
OUTER_LOOP: for(int[] mySimpleArray : myComplexArray) {
INNER_LOOP: for(int i=0; i<mySimpleArray.length; i++) {
        System.out.print(mySimpleArray[i]+"\t");
    }
    System.out.println();
}

Labels follow the same rules for formatting as identifiers. For readability, they are commonly expressed using uppercase letters, with underscores between words, to distinguish them from regular variables. When dealing with only one loop, labels do not add any value, but as we’ll see in the next section, they are extremely useful in nested structures.

73
Q

While this topic is not on the exam, it is possible to add optional labels to control and block statements. For example, the following is permitted by the compiler, albeit extremely uncommon:
~~~
int frog = 15;
BAD_IDEA: if(frog>10)
EVEN_WORSE_IDEA: {
frog++;
}
~~~

A
74
Q

THE BREAK STATEMENT

A

a break statement transfers the flow of control out to the enclosing statement.

break statement can take an optional label parameter. Without a label parameter, the break statement will terminate the nearest inner loop it is currently in the process of executing. The optional label parameter allows us to break out of a higher-level outer loop.

75
Q

In the following example, we search for the first (x,y) array index position of a number within an unsorted two-dimensional array:
~~~
public class FindInMatrix {
public static void main(String[] args) {
int[][] list = {{1,13},{5,2},{2,2}};
int searchValue = 2;
int positionX = -1;
int positionY = -1;
PARENT_LOOP: for(int i=0; i<list.length; i++) {
for(int j=0; j<list[i].length; j++) {
if(list[i][j]==searchValue) {
positionX = i;
positionY = j;
break PARENT_LOOP;
}
}
}
if(positionX==-1 || positionY==-1) {
System.out.println(“Value “+searchValue+” not found”);
} else {
System.out.println(“Value “+searchValue+” found at: “ + “(“+positionX+”,”+positionY+”)”);
}
}
}
~~~

A

When executed, this code will output the following:
Value 2 found at: (1,1)

In particular, take a look at the statement break PARENT_LOOP. This statement will break out of the entire loop structure as soon as the first matching value is found. Now, imagine what would happen if we replaced the body of the inner loop with the following:
~~~
if(list[i][j]==searchValue) {
positionX = i;
positionY = j;
break;
}
~~~
How would this change our flow, and would the output change? Instead of exiting when the first matching value is found, the program will now only exit the inner loop when the condition is met. In other words, the structure will now find the first matching value of the last inner loop to contain the value, resulting in the following output:
Value 2 found at: (2,0)

Finally, what if we removed the break altogether?
~~~
if(list[i][j]==searchValue) {
positionX = i;
positionY = j;
}
~~~

In this case, the code will search for the last value in the entire structure that has the matching value. The output will look like this:
Value 2 found at: (2,1)

You can see from this example that using a label on a break statement in a nested loop, or not using the break statement at all, can cause the loop structure to behave quite differently.

76
Q

THE CONTINUE STATEMENT

A

the continue statement, a statement that causes flow to finish the execution of the current loop.

You may notice the syntax of the continue statement mirrors that of the break statement. In fact, the statements are identical in how they are used, but with different results. While the break statement transfers control to the enclosing statement, the continue statement transfers control to the boolean expression that determines if the loop should continue. In other words, it ends the current iteration of the loop. Also, like the break statement, the continue statement is applied to the nearest inner loop under execution using optional label statements to override this behavior.

77
Q

Let’s take a look at an example. Imagine we have a zookeeper who is supposed to clean the first leopard in each of four stables but skip stable b entirely.
~~~
1: public class CleaningSchedule {
2: public static void main(String[] args) {
3: CLEANING: for(char stables = ‘a’; stables<=’d’; stables++) {
4: for(int leopard = 1; leopard<4; leopard++) {
5: if(stables==’b’ || leopard==2) {
6: continue CLEANING;
7: }
8: System.out.println(“Cleaning: “+stables+”,”+leopard);
9: } } } }
~~~

A

With the structure as defined, the loop will return control to the parent loop any time the first value is b or the second value is 2. On the first, third, and fourth executions of the outer loop, the inner loop prints a statement exactly once and then exits on the next inner loop when leopard is 2. On the second execution of the outer loop, the inner loop immediately exits without printing anything since b is encountered right away. The following is printed:
~~~
Cleaning: a,1
Cleaning: c,1
Cleaning: d,1
~~~

Now, imagine we removed the CLEANING label in the continue statement so that control is returned to the inner loop instead of the outer. Line 6 becomes the following:

6: continue;

This corresponds to the zookeeper skipping all leopards except those labeled 2 or in stable b. The output would then be the following:
~~~
Cleaning: a,1
Cleaning: a,3
Cleaning: c,1
Cleaning: c,3
Cleaning: d,1
Cleaning: d,3
~~~
Finally, if we remove the continue statement and associated if statement altogether by removing lines 5–7, we arrive at a structure that outputs all the values, such as this:
~~~
Cleaning: a,1
Cleaning: a,2
Cleaning: a,3
Cleaning: b,1
Cleaning: b,2
Cleaning: b,3
Cleaning: c,1
Cleaning: c,2
Cleaning: c,3
Cleaning: d,1
Cleaning: d,2
Cleaning: d,3
~~~

78
Q

THE RETURN STATEMENT

A

creating methods and using return statements can be used as an alternative to using labels and break statements.

public class FindInMatrixUsingReturn {
    private static int[] searchForValue(int[][] list, int v) {
        for (int i = 0; i < list.length; i++) {
            for (int j = 0; j < list[i].length; j++) {
                if (list[i][j] == v) {
                    return new int[] {i,j};
                }
            }
        }
        return null;
    }
    public static void main(String[] args) {
        int[][] list = { { 1, 13 }, { 5, 2 }, { 2, 2 } };
        int searchValue = 2;
        int[] results = searchForValue(list,searchValue);
        if (results == null) {
            System.out.println("Value " + searchValue + " not found");
        } else {
            System.out.println("Value " + searchValue + " found at: " + "(" + results[0] + "," + results[1] + ")");
        }
		}
}

This class is functionally the same as the first FindInMatrix class we saw earlier using break. If you need finer-grained control of the loop with multiple break and continue statements, the first class is probably better. That said, we find code without labels and break statements a lot easier to read and debug. Also, making the search logic an independent function makes the code more reusable and the calling main() method a lot easier to read.
For the exam, you will need to know both forms. Just remember that return statements can be used to exit loops quickly and can lead to more readable code in practice, especially when used with nested loops.

79
Q

UNREACHABLE CODE

A

One facet of break, continue, and return that you should be aware of is that any code placed immediately after them in the same block is considered unreachable and will not compile.

For example, the following code snippet does not compile:
~~~
int checkDate = 0;
while(checkDate<10) {
checkDate++;
if(checkDate>100) {
break;
checkDate++; // DOES NOT COMPILE
}
}
~~~

Even though it is not logically possible for the if statement to evaluate to true in this code sample, the compiler notices that you have statements immediately following the break and will fail to compile with “unreachable code” as the reason.

80
Q
int minute = 1;
WATCH: while(minute>2) {
    if(minute++>2) {
        continue WATCH;
        System.out.print(minute); // DOES NOT COMPILE
    }
}

int hour = 2;
    switch(hour) {
        case 1: return; hour++; // DOES NOT COMPILE
        case 2:
    }
A

the compiler notices that you have statements immediately following the break and will fail to compile with “unreachable code” as the reason. The same is true for continue and returnstatements too,

81
Q

One thing to remember is that it does not matter if loop or decision structure actually visits the line of code. For example, the loop could execute zero or infinite times at runtime. Regardless of execution, the compiler will report an error if it finds any code it deems unreachable, in this case any statements immediately following a break, continue, or return statement.

A
82
Q

REVIEWING BRANCHING

A
  1. while
    - Allow optional labels
    - Allow break statement
    - Allow continue statement
  2. do/while
    - Allow optional labels
    - Allow break statement
    - Allow continue statement
  3. for
    - Allow optional labels
    - Allow break statement
    - Allow continue statement
  4. switch
    - Allow optional labels
    - Allow break statement
    - Not allow continue statement
83
Q

Exam Essentials

A

Understand if and else decision control statements. The if and else statements come up frequently throughout the exam in questions unrelated to decision control, so make sure you fully understand these basic building blocks of Java.

Understand switch statements and their proper usage. You should be able to spot a poorly formed switch statement on the exam. The switch value and data type should be compatible with the case statements, and the values for the case statements must evaluate to compile-time constants. Finally, at runtime a switch statement branches to the first matching case, or default if there is no match, or exits entirely if there is no match and no default branch. The process then continues into any proceeding case or default statements until a break or return statement is reached.

Understand while loops. Know the syntactical structure of all while and do/while loops. In particular, know when to use one versus the other. Be able to use for loops. You should be familiar with for and for-each loops and know how to write and evaluate them. Each loop has its own special properties and structures. You should know how to use for-each loops to iterate over lists and arrays.

Understand how break, continue, and return can change flow control. Know how to change the flow control within a statement by applying a break, continue, or return statement. Also know which control statements can accept break statements and which can accept continue statements. Finally, you should understand how these statements work inside embedded loops or switch statements.

84
Q

Summary

A

This chapter presented how to make intelligent decisions in Java. We covered basic decision-making constructs such as if, else, and switch statements and showed how to use them to change the path of process at runtime. Remember that the switch statement allows a lot of data types it did not in the past, such as String, enum, and in certain cases var.

We then moved our discussion to repetition control structures, starting with while and do/while loops. We showed how to use them to create processes that looped multiple times and also showed how it is important to make sure they eventually terminate. Remember that most of these structures require the evaluation of a particular boolean expression to complete.

Next, we covered the extremely convenient repetition control structures, for and for-each loops. While their syntax is more complex than the traditional while or do/while loops, they are extremely useful in everyday coding and allow you to create complex expressions in a single line of code. With a for-each loop you don’t need to explicitly write a boolean expression, since the compiler builds one for you. For clarity, we referred to an enhanced for loop as a for-each loop, but syntactically both are written using the for keyword.

We concluded this chapter by discussing advanced control options and how flow can be enhanced through nested loops, coupled with break, continue, and return statements. Be wary of questions on the exam that use nested loops, especially ones with labels, and verify they are being used correctly.

This chapter is especially important because at least one component of this chapter will likely appear in every exam question with sample code. Many of the questions on the exam focus on proper syntactic use of the structures, as they will be a large source of questions that end in “Does not compile.” You should be able to answer all of the review questions correctly or fully understand those that you answered incorrectly before moving on to later chapters.