Accompanying code files:
- N/A
Jump to Homework
Once again, we are going over in more detail what we touched very briefly on in Lesson 02. By using control structures, you can make statements of a program run in a non-sequential order, such as for decision-making or iteration.
- An if statement is a conditional statement; it allows the program to execute a specific set of instructions if some certain (Boolean) condition (usually based on the program inputs) is met, and skipping those instructions otherwise.
- These are used when there is only 1 possible outcome for the condition.
if (hasAllInfinityStones) {
snapFingers(); // executed if and only if above condition is met
}
if (hasAllInfinityStones)
snapFingers(); // statement (syntactically valid if only 1 line of code)
- An if-else statement also provides an alternative route of control flow for when the condition is not met, so they are used when there are 2 possible outcomes for the condition, causing a branch in the control flow.
if (isHappy) {
System.out.println('Monkey loves you!'); // executed if and only if above condition is met
} else {
System.out.println('Monkey needs a hug.'); // executed otherwise
}
if (isHappy)
System.out.println('Monkey loves you!'); // syntactically valid as above as if-clause is one line
else
System.out.println('Monkey needs a hug.'); // syntactically valid as above as else-clause is one line
- There is also a short-form of the if-else statement using the ? and : operators:
if (chromosome[22] == "XX") {
sex = "Female";
} else {
sex = "Male";
}
sex = (chromosome[22] == "XX") ? "Female" : "Male"; // this is semantically equivalent to above
- A nested if statement is an if-statement within an if statement, usually used for sequential conditions, where the inner if statement's condition is only worth checking if the outer if statement's condition is met.
if (wizard.getSchool() == "Hogwarts") { // 1st condition
if (wizard.getGPA() >= 3.5) {// 2nd condition that is only checked if and only if 1st condition is met
wizard.setHouse("Ravenclaw");
}
}
if (wizard.getSchool() == "Hogwarts" && wizard.getGPA() >= 3.5) // due to Java's short-circuit evaluation, this is semantically equivalent to the above style
wizard.setHouse("Ravenclaw");
- Extended if statements are for when there are multiple different paths that control can flow to.
if (this.name = "Stark") {
return "Winter Is Coming";
} else if (this.name = "Lannister") {
return "Hear Me Roar";
} else if (this.name = "Targaryen") {
return "Fire And Blood";
} else if (this.name = "Greyjoy") {
return "We Do Not Sow";
} else if (this.name = "Baratheon") {
return "Ours Is The Fury";
} else if (this.name = "Tyrell") {
return "Growing Strong";
} else if (this.name = "Martell") {
return "Unbowed. Unbent. Unbroken.";
} else if (this.name = "Tully") {
return "Family. Duty. Honour";
} else {
return "As High As Honour"; // this will be returned if this.name is anything other than the previous values tested
}
// code below is semantically equivalent to above
if (this.name = "Stark")
return "Winter Is Coming";
else if (this.name = "Lannister")
return "Hear Me Roar";
else if (this.name = "Targaryen")
return "Fire And Blood";
else if (this.name = "Greyjoy")
return "We Do Not Sow";
else if (this.name = "Baratheon")
return "Ours Is The Fury";
else if (this.name = "Tyrell")
return "Growing Strong";
else if (this.name = "Martell")
return "Unbowed. Unbent. Unbroken.";
else if (this.name = "Tully")
return "Family. Duty. Honour";
else
return "As High As Honour";
}
- While using the one-line style without curly braces often looks neater and is more readable, be mindful of indentation to avoid creating dangling else cases when combining nested if statements with if-else statements.
- The else-clause will always get matched to the nearest unpaired if statement.
public void TransferCourse(Course course) {
if (course.isValid())
if (course.getGrade() >= 4)
course.setCreditsEarned(true);
System.out.println("Course " + course.getCourseCode() + " transferred successfully.");
else
System.out.println("Course is not offered at this institution.");
}
- In the above example, if the course was valid but had a grade of 2,
Course is not offered at this institution.
in the else clause would be printed to the console, because the closest if statement to it is the inner one (whose condition is not met). - Note that if the course was invalid in the first place,
Course is not offered at this institution.
would be printed correctly since the inner if statement will not be reached at all.
- The scope of a variable or method is the region in which that variable or method is visible and can be accessed.
- The instance variables, static variables, and methods or a specific class all belong to that class' scope, which extends from the opening brace
{
to the closing brace}
of the class definition. This is known as lexical scoping or static scoping, is determined when the code is compiled, and is a convention used by many programming languages (instead of dynamic scoping). - Within the class, all instance variables and methods are accessible and can be referred to simply by name (no need to call it as
ClassName.classMethod()
, justclassMethod()
) - A local variable is defined inside a method or even a statement, and its scope extends from the point where it is declared to the end of the code block in which its declaration occurs.
- A block a section of code enclosed in a pair of braces
{}
, and control flow exits a block, the memory for a local variable is automatically recycled (i.e. variable no longer exists in memory). - Local variables take precedence over instance variables with the same name, which is why using the same name can lead to ambiguity and errors and should generally be avoided
public class Pokemon {
public String name;
// Constructor
public Pokemon(String name) {
this.name = name; // using the this keyword is necessary because the name of the data field and parameter are the same
}
// Constructor
public Pokemon(String n) {
name = n; // using the this keyword is not necessary here because the parameter and data field have different names
}
// Changes name of Pokemon instance
public void setName(String name) {
n = name; // n will only exist in memory until the end of the code block of this method
name = n; // actual name of Pokemon object will not be changed because the default name used is the parameter
}
public String getName() {
return n; // will cause an error because n does not exist as a variable/method in the Pokemon class
}
} // anything outside of this brace has to call getName() as Pokemon.getName()
We did the following questions in class, and from your most recent MCQ question set:
- Consider the following code segment.
int num1 = 9;
int num2 = 5;
if (num1 > num2)
{
System.out.print((num1 + num2) % num2);
}
else
{
System.out.print((num1 - num2) % num2);
}
What is printed as a result of executing the code segment?
- (A) 0
- (B) 2
- (C) 4
- (D) 9
- (E) 14
- Consider the following code segment.
int value = initValue;
if (value > 10)
if (value > 15)
value = 0;
else
value = 1;
System.out.println("value = " + value);
Under which of the conditions below will this code segment print value = 1
?
- (A) initValue = 8;
- (B) initValue = 12;
- (C) initValue = 20;
- (D) Never.
value = 0
will always be printed. - (E) Never. Code will not compile.
- Rewrite the following code with the correct syntax:
public class OhNo {
public static void main(String args[]) {
int a = 7,
b = 42;
minimum(a,b);
if {smaller = a} {
System.out.println("a is the smallest!");
}
}
public static void minimum(int a, int b) {
if (a < b) {
int smaller = a;
} else (a = b) {
int smaller = b;
}
return int smaller;
}
}
HINT: There are 7 errors.
- Rewrite the following code to eliminate redundancy while still being semantically equivalent.
if (x < 30) {
a = 2;
x++;
System.out.println("Spongebob Squarepants! " + x);
} else {
a = 2;
System.out.println("Spongebob Squarepants! " + x);
}
ANSWERS:
- C
- B
- The corrected code with explanations is as follows:
public class OhNo {
public static void main(String args[]) {
int a = 7; // #1 - use a semicolon, not a comma
int b = 42; // #2 - b is a new variable, so you need to specify the type
int minimum(a,b); // #3 - when you call an accessor, save the value of something you want to use for later
if (smaller = a) { // #4 - Boolean condition should be within brackets, not braces
System.out.println("a is the smallest!");
}
}
public static int minimum(int a, int b) { // #5 - void doesn't return anything!
if (a < b) {
int smaller = a;
} else { // #6 - else clauses should not have a condition!
int smaller = b;
}
return int smaller; // #7 - don't need to specify the type of an existing variable
}
}
- The idea here is to remove anything that would happen in either case. Always aim to avoid redundancy in your code!
a = 2;
if (x < 30)
x++;
System.out.println("Spongebob Squarepants! " + x);
Introductory Java Language Features Question Set
Q | A |
---|---|
4 | D |
11 | A |
15 | C |
- For loops are great for repeating a set of instructions a set number of times, especially over a collection of items
- As we know, the general form of the for loop is as follows:
for (initialization; termination condition; update statement;) {
// statements in the loop body
}
- It is important to note that the initialization of the loop control variable (LCV) occurs before the first iteration of the loop, the termination condition is tested before the each of the next iteration of the loop, and the update statement is performed at the end of the loop body.
- In other words, the code in the loop body of the following for loop will not be executed at all:
for (i = 0; i == 0; i++;) {
System.out.println("Bears. Beets. Battlestar Galactica.");
}
// This is semantically equivalent to above as there is only one line in the loop body
for (i = 0; i == 0; i++;)
System.out.println("Bears. Beets. Battlestar Galactica.");
- The LCV should also not have its value changed inside the loop body
- The initializing and update statements can use any valid constants, variables, or expressions
- The scope of the LCV can be restricted to the loop body by combining its declaration with its initialization (e.g. by replacing
i = 0
in the initialization withint i = 0
, so that i does not have to initialized before the loop, and only exists within the loop)
Nested For Loops
- Exactly what you think it is: A loop within a loop
- The outer loop control variable (OLCV) is used to control the outer loop, and the inner loop control variable (ILCV) is used to control the inner loop
- There is no limit to the number of times you can nest a series of loops, but with each additional level, the entire structure will take an exponentially longer time to complete (more on this in another topic)
for (OLCV; termination using OLCV; update OLCV) {
for (ILCV; termination using ILCV; update ILCV) {
System.out.println("I'm Mr. Meseeks! Look at me!");
}
}
- For the above code, assuming the inner loop will execute x times, and the outer loop will execute y times, the structure will take xy times to complete
For-Each Loops
- An enhanced type of for loop that is specialized for iterating over collections e.g. arrays
for (SomeType element : collection) {
// statements in the loop body to be executed for each element of some type in the collection
}
- These hide the index variable that is used with arrays
- They should be used for accessing elements, not replacing/removing them as you traverse along the collection
- What if there is a case when you want to exit the loop before the specified termination point? Use the
break
statement to break out of the loop!
- We know that these are very similar to for loops, but are more suitable to use when you don't necessarily know how many iterations are supposed to occur.
- The initialization must occur before the while loop is declared
- The termination condition is a boolean expression and is the only thing in the while loop's brackets
()
- The update statement MUST occur within the loop body, and is usually best done at the end of the loop body
- The termination condition does not necessarily have to include the LCV (but it often does), but the update statement generally has to incorporate the LCV in some way
int i = 0; // initialization
while (i < 10) { // termination condition
// statements in the loop body to be executed if and only if the boolean expression is true
i++; //
}
Infinite Loops
- The termination condition is really important! Using the wrong one could cause the loop to keep iterating indefinitely, since the LCV is never updated to the point where the termination condition is met.
- Infinite loops can happen to for loops, while loops, and even in recursion
- The following will cause infinite loops.
for (int i = 0; i < 10; i--) {
i++; // i is incremented by 1 (i == 1) and then is decremented by 1 (i == 0) at the end of the loop, so loop goes on FOREVER
}
int i = 0;
while (i == 0) {
// do something FOREVER because i is never incremented
}
Boundary Checking
- A boundary error a.k.a. "off-by-one" error is an error where the loop is executed either one too many or too little times
- This concept will be tested many times on the AP Computer Science A Exam
- A good way to prevent this is to start the initialization with 0 e.g.
int i = 0;
, and the termination condition should be one less than the number of times you want the loop to run e.g.i < max;
(loop will runmax
times) assuming i is incremented by 1 each timei++;
- Alternatively, if you prefer to start with
int i = 1
(not recommended for computer science!), the termination condition should bei <= max;
, again assuming the update statement isi++;
We did the following questions in class, and from your most recent MCQ question set:
- Consider the following code segment:
int count = 1;
int value = 31;
while (value >= 10) {
value = value - count;
count = count + 3;
}
System.out.println(value);
What is printed as a result of executing the code segment?
- (A) 4
- (B) 9
- (C) 10
- (D) 13
- (E) 31
- Consider the following code segment:
int count = 5;
for (int i = 3; i < 7; i = i + 2;)
count += i;
System.out.println(count);
What is printed as a result of executing the code segment?
- (A) 5
- (B) 7
- (C) 9
- (D) 13
- (E) 20
- Consider the following code segment:
int incr = 1;
for (int i = 0; i < 10; i+= incr) {
System.out.print(i - incr + " ");
incr++;
}
What is printed as a result of executing the code segment?
- (A) -1 0 2 5
- (B) -1 0 3 7
- (C) -1 1 4 8
- (D) 0 2 5 9
- (E) 0 1 3 7
- Which of the following code segments will print exactly eight
$
symbols?
// SEGMENT I
for (int i = 0; i < 8; i++)
System.out.print("$");
// SEGMENT II
int i = 0;
while (i < 8) {
System.out.print("$");
i++;
}
// SEGMENT III
for (int i = 7; i <= 30); i += 3)
System.out.print("$");
- (A) I only
- (B) II only
- (C) I and II only
- (D) I and III only
- (E) I, II, and III
- Consider the following code segment:
for (int j = 0; j < 10; j++) {
for (int k = 10; k > j; k--;) {
System.out.print("*");
}
}
How many *
symbols are printed as a result of executing the code segment?
- (A) 5
- (B) 10
- (C) 45
- (D) 55
- (E) 100
- Consider the following code segment:
boolean b1 = true;
boolean b1 = true;
boolean b2 = true;
int x = 7;
while (b1 || b2) {
if (x > 4)
b2 = !b2;
else
b1 = !b1;
x--;
}
System.out.print(x);
What is printed as a result of executing the code segment?
- (A) 3
- (B) 4
- (C) 6
- (D) 7
- (E) Nothing will be printed. Infinite loop.
- Which of the following three code segments will produce the same output?
// SEGMENT I
int i = 1;
while (i < 12) {
System.out.print(i + " ");
i *= 2;
}
// SEGMENT II
for (int i = 4; i > 0; i--)
System.out.print((4 - i) * 2 + 1 + " ");
// SEGMENT III
for (int i = 0; i < 4; i++)
System.out.print((int) Math.pow(2, i) + " ");
- (A) I and II only
- (B) II and III only
- (C) I and III only
- (D) I, III, and III
- (E) All the outputs are different.
- Consider the following code segment:
double count = 6.0;
for (int num = 0; num < 5; num++) {
if (count != 0 && num / count > 0)
count -= num;
}
System.out.println(count);
What is printed as a result of executing the code segment?
- (A) 0.0
- (B) -4.0
- (C) 5
- (D) The program will end successfully, but nothing will be printed.
- (E) Nothing will be printed. Run-time error: ArithmeticException.
- Consider the following code segment:
int n = 0;
while (n < 20) {
System.out.print(n % 4 + " ");
if (n % 5 == 2)
n += 4;
else
n += 3;
}
What is printed as a result of executing the code segment?
- (A) 0 3 2 1 0 0 3
- (B) 0 0 3 2 2 1
- (C) 0 3 2 1 0 0
- (D) 0 0 3 2 2 1 0
- (E) Many numbers will be printed. Infinite loop.
ANSWERS:
- B
- D
- A
- E
- D
- A
- C
- A
- A
Assignments:
- From the Introductory Java Language Features Question Set, complete questions: 16, 17, 21, 24, 25, 26, and 27.
- Answers will be posted on the Topic 2 assignment answers issue.
Prep for Next Class:
- Review Lesson 2 Notes again.