Midterm Review and Synthesis
Connecting Weeks 1–5 — types, expressions, conditionals, loops, and methods
After this lesson, you will be able to:
- Trace code through method calls and the call stack
- Identify the correct type, operator, or pattern for a given problem
- Solve code-tracing problems involving mixed types, casting, and precedence
- Write methods that combine loops, conditionals, and return values
- Apply the full Weeks 1–5 toolkit to multi-step problems
The Big Picture: Everything Connects
Over the past five weeks, you have learned individual tools: types, expressions, conditionals, loops, methods, and Scanner. On their own, each is straightforward. The challenge — and the skill the midterm tests — is combining them. A single exam problem might require you to trace a method call that involves type promotion, a loop with an accumulator, and a conditional return.
This lesson connects all the pieces. No new concepts — just synthesis and practice.
From CSCD 110: In Python, you wrote programs that combined variables, loops, functions, and conditionals. Java adds static types, explicit method signatures, and the call stack. The logic is the same; the bookkeeping is more explicit.
Topic Map: What You Know
| Topic | Key Concepts | Common Traps |
|---|---|---|
| Types | int, double, boolean, char, String |
int division truncates; String is a reference type |
| Expressions | Arithmetic, boolean, concatenation; precedence | "x" + 2 + 3 → "x23"; 10 / 4 → 2 |
| Casting | Widening (auto), narrowing (explicit) | (double)(x/y) truncates first; (int)3.99 → 3 |
| Conditionals | if/else, switch, ternary, &&/|| |
Chained comparisons invalid; == fails for Strings |
| Loops | for, while, do-while; six patterns |
Off-by-one; wrong initialization; fencepost |
| Methods | Parameters, return, overloading, scope | Pass-by-value; scope dies at }; can’t overload by return type |
| Scanner | nextInt, nextLine, hasNextInt |
Buffer trap; validate before use |
Skill 1: Code Tracing
The most common exam task. Given code, predict the output step by step.
Trace 1: Mixed Types and Precedence
int a = 17, b = 5;
double c = a / b;
double d = (double) a / b;
System.out.println(c + " " + d);
Trace:
a / b→17 / 5→3(bothint, integer division)c = 3→ widened to3.0(double) a / b→17.0 / 5→3.4- Output:
3.0 3.4
Trace 2: String Concatenation
int x = 10, y = 20;
System.out.println(x + y);
System.out.println("" + x + y);
System.out.println(x + y + "");
System.out.println("Sum: " + (x + y));
Output:
30
1020
30
Sum: 30
Line 2: "" + 10 → "10", then "10" + 20 → "1020". Line 3: 10 + 20 → 30, then 30 + "" → "30".
What does System.out.println(1 + 2 + "abc" + 3 + 4); print?
Skill 2: Call-Stack Tracing
When a method is called, Java creates a stack frame with its own local variables. When the method returns, the frame is removed:
public static int doubled(final int n) {
return n * 2;
}
public static int addDoubles(final int a, final int b) {
int x = doubled(a);
int y = doubled(b);
return x + y;
}
public static void main(String[] args) {
int result = addDoubles(3, 5);
System.out.println(result);
}
Call-stack trace:
1. main() calls addDoubles(3, 5)
2. addDoubles(3,5) calls doubled(3)
3. doubled(3) returns 6
4. addDoubles(3,5) x=6, calls doubled(5)
5. doubled(5) returns 10
6. addDoubles(3,5) y=10, returns 6+10=16
7. main() result=16, prints 16
Each method has its own n, its own a and b, its own x and y. They cannot interfere with each other.
Key Insight: Pass-by-value means each method gets a copy of the argument. Changing a parameter inside a method does not affect the caller’s variable. This is why the “swap” function cannot work with primitive types in Java.
What does this code print?
static int mystery(int x) { x = x + 10; return x; }
int a = 5; int b = mystery(a); System.out.println(a + " " + b);
Skill 3: Writing Methods from Descriptions
Problem: “Write a method that takes an array of integers and returns the count of even numbers.”
Step 1 — Identify IPO:
- Input: an
intvaluen(the upper bound) - Process: loop 1 to n, count even numbers
- Output: return the count
Step 2 — Choose patterns: counter pattern (initialize to 0, increment on condition)
public static int countEvenUpTo(final int n) {
int count = 0;
for (int i = 1; i <= n; i++) {
if (i % 2 == 0) {
count++;
}
}
return count;
}
Problem: “Write a method that returns true if a given integer is prime.”
public static boolean isPrime(final int n) {
if (n < 2) {
return false;
}
for (int i = 2; i * i <= n; i++) {
if (n % i == 0) {
return false;
}
}
return true;
}
Skill 4: Combined Problems
These problems require multiple concepts working together.
Problem: Statistics with Validation
Read numbers from the user until they enter -1 (sentinel). Track the count, sum, max, and min. Reject non-positive numbers (except the sentinel).
import java.util.Scanner;
public class ValidatedStats {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int count = 0;
int sum = 0;
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
System.out.print("Enter a number (-1 to stop): ");
int value = scanner.nextInt();
while (value != -1) {
if (value <= 0) {
System.out.println("Skipping non-positive: " + value);
} else {
count++;
sum += value;
if (value > max) { max = value; }
if (value < min) { min = value; }
}
System.out.print("Enter a number (-1 to stop): ");
value = scanner.nextInt();
}
if (count == 0) {
System.out.println("No valid numbers entered.");
} else {
System.out.println("Count: " + count);
System.out.println("Sum: " + sum);
System.out.printf("Average: %.2f%n", (double) sum / count);
System.out.println("Max: " + max);
System.out.println("Min: " + min);
}
}
}
This combines: sentinel loop, input validation, four accumulator patterns, casting for the average, and a conditional edge case (no valid input).
The Three Comparison Rules
These appear on nearly every exam. Memorize them:
| Type | How to Compare | Why |
|---|---|---|
int, double, char |
a == b |
Primitives hold values directly |
double (precision) |
Math.abs(a - b) < epsilon |
Floating-point is imprecise |
String |
a.equals(b) |
Reference types; == compares addresses |
Which of these correctly checks if two double values are approximately equal?
Quick Reference: The Complete Weeks 1–5 Toolkit
Types: int (whole numbers), double (decimals), boolean (true/false), char (single character), String (text)
Operators: + - * / % (arithmetic); && || ! (logical); == != < > <= >= (comparison); += -= ++ -- (compound)
Casting: (double) x widens; (int) x narrows (truncates); Math.round(x) rounds
Conditionals: if/else, else if, switch, ternary (? :)
Loops: for (known count), while (unknown count), do-while (at least once)
Patterns: Counter (init 0, ++), Sum (init 0, +=), Product (init 1, *=), Max (init MIN_VALUE), Min (init MAX_VALUE), Flag (init false)
Methods: static returnType name(params), overloading, scope, pass-by-value
Scanner: nextInt(), nextDouble(), nextLine(), next(), hasNextInt(); buffer trap fix
Summary
The midterm tests your ability to combine individual tools into working programs. Code tracing requires you to step through expressions, type promotion, and method calls line by line. Writing methods requires identifying the IPO pattern, choosing the right loop pattern, and handling edge cases.
The three comparison rules (== for primitives, epsilon for doubles, .equals() for Strings), the six loop patterns (ZOM-FMF), and the call stack (pass-by-value, scope isolation) are the most-tested concepts.
This is the end of the Java Foundations series. Everything you have learned — types, expressions, conditionals, loops, methods — forms the foundation for the second half of the course: arrays, file I/O, objects, and interfaces.