java-foundations Lesson 12 22 min read

Midterm Review and Synthesis

Connecting Weeks 1–5 — types, expressions, conditionals, loops, and methods

Reading: Reges & Stepp: Ch. 1–5 (review)

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 / 42
Casting Widening (auto), narrowing (explicit) (double)(x/y) truncates first; (int)3.993
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:

  1. a / b17 / 53 (both int, integer division)
  2. c = 3 → widened to 3.0
  3. (double) a / b17.0 / 53.4
  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 + 2030, then 30 + """30".

Check Your Understanding

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.

Check Your Understanding

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 int value n (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
Check Your Understanding

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.