AP CSA Unit 4: Data Collections - Ultimate Study Guide 2025-2026
AP Computer Science A
Ultimate Study Guide - 2025-2026 Curriculum
Unit 4 Overview
Unit 4: Data Collections is the largest and most important unit on the AP CSA Exam. It covers everything from basic arrays to complex algorithms, and accounts for nearly 40% of your exam score. Master this unit, and you're well on your way to a 4 or 5.
Plus TWO of the four Free Response Questions:
- FRQ #3: Data Analysis with ArrayList - traverse, filter, and process ArrayList data
- FRQ #4: 2D Array - nested loops, row/column processing, grid manipulation
This means Unit 4 content appears in roughly 50% of your total exam score!
What's New for 2025-2026
The College Board added reading from text files using the File and Scanner classes. This is practical, real-world programming that connects to data analysis. You'll need to know:
-
hasNext(),nextLine(),nextInt(),next() - The
throws IOExceptionclause - Processing file data into arrays or ArrayLists
Unit 4 Topic Breakdown
| Topic | Content | Exam Focus |
|---|---|---|
| 4.1 | Ethical & Social Issues Around Data Collection | Conceptual MCQ |
| 4.2 | Introduction to Using Data Sets | Conceptual MCQ |
| 4.3 | Array Creation and Access | MCQ, FRQ 3 & 4 |
| 4.4 | Array Traversals | MCQ, FRQ 3 & 4 |
| 4.5 | Implementing Array Algorithms | MCQ, FRQ 3 & 4 |
| 4.6 | Using Text Files NEW | MCQ, possibly FRQ |
| 4.7 | Wrapper Classes (Integer, Double) | MCQ, FRQ 3 |
| 4.8 | ArrayList Methods | Heavy MCQ, FRQ 3 |
| 4.9 | ArrayList Traversals | Heavy MCQ, FRQ 3 |
| 4.10 | Implementing ArrayList Algorithms | Heavy MCQ, FRQ 3 |
| 4.11 | 2D Array Creation and Access | Heavy MCQ, FRQ 4 |
| 4.12 | 2D Array Traversals | Heavy MCQ, FRQ 4 |
| 4.13 | Implementing 2D Array Algorithms | Heavy MCQ, FRQ 4 |
| 4.14 | Searching Algorithms | MCQ (tracing) |
| 4.15 | Sorting Algorithms | MCQ (tracing) |
| 4.16 | Recursion | MCQ (tracing) |
| 4.17 | Recursive Searching and Sorting | MCQ (tracing) |
Skills You'll Master
- Create, access, and modify arrays, ArrayLists, and 2D arrays
- Write traversal loops (standard for, enhanced for, backward)
- Implement standard algorithms: sum, average, min/max, count, search, filter
- Read data from text files
- Trace searching algorithms (linear and binary search)
- Trace sorting algorithms (selection and insertion sort)
- Understand and trace recursive methods
- Avoid common pitfalls that lose points on FRQs
Arrays
An array is a container that holds a fixed number of values of a single type. Once created, an array's size cannot change. Arrays are the foundation of data collections in Java.
Creating Arrays
Method 1: Declare Size (Elements Get Default Values)
// Create array of 5 integers - all initialized to 0
int[] numbers = new int[5];
// numbers = [0, 0, 0, 0, 0]
// Create array of 3 Strings - all initialized to null
String[] names = new String[3];
// names = [null, null, null]
// Create array of 4 doubles - all initialized to 0.0
double[] prices = new double[4];
// prices = [0.0, 0.0, 0.0, 0.0]
// Create array of 2 booleans - all initialized to false
boolean[] flags = new boolean[2];
// flags = [false, false]
Method 2: Initialize with Values (Size is Inferred)
// Initialize with specific values
int[] scores = {85, 90, 78, 92, 88};
// scores.length = 5
String[] colors = {"red", "green", "blue"};
// colors.length = 3
double[] temps = {98.6, 99.1, 97.8};
// temps.length = 3
Default Values by Type
| Element Type | Default Value | Example |
|---|---|---|
int |
0 |
new int[3] → [0, 0, 0] |
double |
0.0 |
new double[2] → [0.0, 0.0] |
boolean |
false |
new boolean[2] → [false, false] |
String (and all objects) |
null |
new String[2] → [null, null] |
Accessing and Modifying Elements
int[] arr = {10, 20, 30, 40, 50};
// Access elements using index (0-based!)
System.out.println(arr[0]); // 10 (first element)
System.out.println(arr[2]); // 30 (third element)
System.out.println(arr[4]); // 50 (last element)
// Get array length (NOT a method - no parentheses!)
System.out.println(arr.length); // 5
// Access last element (common pattern)
System.out.println(arr[arr.length - 1]); // 50
// Modify elements
arr[0] = 100; // arr = [100, 20, 30, 40, 50]
arr[2] = 300; // arr = [100, 20, 300, 40, 50]
arr[4] = arr[3] + 10; // arr = [100, 20, 300, 40, 50]
Array Index Diagram
// Visual representation of array indexing:
//
// Index: 0 1 2 3 4
// +-----+-----+-----+-----+-----+
// arr: | 10 | 20 | 30 | 40 | 50 |
// +-----+-----+-----+-----+-----+
//
// arr.length = 5
// Valid indices: 0, 1, 2, 3, 4
// First element: arr[0]
// Last element: arr[arr.length - 1] = arr[4]
Accessing an index less than 0 or greater than or equal to length causes a runtime crash:
int[] arr = {10, 20, 30}; // length = 3, valid indices: 0, 1, 2
arr[3] // CRASH! Index 3 doesn't exist
arr[-1] // CRASH! Negative indices don't exist
arr[arr.length] // CRASH! This equals arr[3]
This is the #1 runtime error on the AP exam. Always check your loop bounds!
Arrays of Objects
// Array of String objects
String[] words = new String[3];
// words = [null, null, null] - NOT empty strings!
words[0] = "Hello";
words[1] = "World";
// words = ["Hello", "World", null]
// Calling methods on null causes NullPointerException!
words[2].length() // CRASH! words[2] is null
// Safe pattern: check for null first
if (words[2] != null)
{
System.out.println(words[2].length());
}
- Array size is FIXED once created - you cannot add or remove elements
- Use
arr.length(no parentheses) to get size - Indices go from
0tolength - 1 - Object arrays initialize to
null, not empty objects - Arrays can hold primitives OR objects, but not both in the same array
Array Traversals
Traversing an array means visiting each element, typically to read, process, or modify the values. There are several traversal patterns you need to know.
Pattern 1: Standard for Loop
Use when you need the index, need to modify elements, or need to access adjacent elements.
int[] arr = {10, 20, 30, 40, 50};
// Forward traversal (most common)
for (int i = 0; i < arr.length; i++)
{
System.out.println("Index " + i + ": " + arr[i]);
}
// Output:
// Index 0: 10
// Index 1: 20
// Index 2: 30
// Index 3: 40
// Index 4: 50
for (int i = 0; i < arr.length; i++) // ✔ CORRECT
for (int i = 0; i <= arr.length; i++) // WRONG - causes crash!
If arr.length is 5, then i <= 5 tries to access arr[5], which doesn't exist!
Pattern 2: Enhanced for Loop (for-each)
Use when you only need to READ values and don't need the index.
int[] arr = {10, 20, 30, 40, 50};
// Enhanced for loop - simpler syntax for reading
for (int num : arr)
{
System.out.println(num);
}
// Output: 10, 20, 30, 40, 50 (each on new line)
// Read as: "for each int num in arr"
int[] arr = {10, 20, 30};
// This does NOT modify the array!
for (int num : arr)
{
num = num * 2; // Only changes the local copy!
}
// arr is STILL [10, 20, 30] - unchanged!
// To modify, you MUST use standard for loop:
for (int i = 0; i < arr.length; i++)
{
arr[i] = arr[i] * 2; // This DOES modify the array
}
// arr is now [20, 40, 60]
The variable in an enhanced for loop is a copy of each element, not a reference to it!
Pattern 3: Backward Traversal
Essential for certain algorithms (like removing from ArrayList).
int[] arr = {10, 20, 30, 40, 50};
// Start at last index, go down to 0
for (int i = arr.length - 1; i >= 0; i--)
{
System.out.println(arr[i]);
}
// Output: 50, 40, 30, 20, 10
Pattern 4: Partial Traversal
int[] arr = {10, 20, 30, 40, 50, 60};
// First half only
for (int i = 0; i < arr.length / 2; i++)
{
System.out.print(arr[i] + " ");
}
// Output: 10 20 30
// Second half only
for (int i = arr.length / 2; i < arr.length; i++)
{
System.out.print(arr[i] + " ");
}
// Output: 40 50 60
// Every other element (even indices)
for (int i = 0; i < arr.length; i += 2)
{
System.out.print(arr[i] + " ");
}
// Output: 10 30 50
// Every other element (odd indices)
for (int i = 1; i < arr.length; i += 2)
{
System.out.print(arr[i] + " ");
}
// Output: 20 40 60
Pattern 5: Accessing Adjacent Elements
int[] arr = {10, 20, 30, 40, 50};
// Compare each element with the next one
for (int i = 0; i < arr.length - 1; i++) // Note: length - 1!
{
if (arr[i] < arr[i + 1])
{
System.out.println(arr[i] + " < " + arr[i + 1]);
}
}
// Compare each element with the previous one
for (int i = 1; i < arr.length; i++) // Note: start at 1!
{
if (arr[i] > arr[i - 1])
{
System.out.println(arr[i] + " > " + arr[i - 1]);
}
}
| Situation | Use |
|---|---|
| Just reading values | Enhanced for loop |
| Need the index | Standard for loop |
| Modifying elements | Standard for loop |
| Comparing adjacent elements | Standard for loop |
| Traversing backward | Standard for loop |
| Skipping elements (every other) | Standard for loop |
Traversal with Strings
String[] words = {"apple", "banana", "cherry"};
// Using enhanced for loop
for (String word : words)
{
System.out.println(word.toUpperCase());
}
// Output: APPLE, BANANA, CHERRY
// Check for null before calling methods!
String[] mixed = {"hello", null, "world"};
for (String s : mixed)
{
if (s != null) // Prevent NullPointerException
{
System.out.println(s.length());
}
}
Array Algorithms
These standard algorithms appear constantly on the AP exam. Memorize these patterns!
Algorithm 1: Sum of Elements
int[] arr = {10, 20, 30, 40, 50};
int sum = 0; // Accumulator starts at 0
for (int num : arr)
{
sum = sum + num; // Or: sum += num;
}
System.out.println(sum); // 150
Algorithm 2: Average of Elements
int[] arr = {10, 20, 30, 40, 50};
int sum = 0;
for (int num : arr)
{
sum += num;
}
// IMPORTANT: Cast to double for decimal result!
double average = (double) sum / arr.length;
System.out.println(average); // 30.0
// Without cast: 150 / 5 = 30 (integer division)
// With cast: 150.0 / 5 = 30.0 (decimal division)
Algorithm 3: Find Maximum
int[] arr = {23, 45, 12, 67, 34};
// Initialize to FIRST element, not 0!
int max = arr[0];
for (int i = 1; i < arr.length; i++) // Start at 1
{
if (arr[i] > max)
{
max = arr[i];
}
}
System.out.println(max); // 67
int[] arr = {-5, -3, -8, -1};
int max = 0; // WRONG! What if all elements are negative?
// max would remain 0, which isn't even in the array!
int max = arr[0]; // ✔ CORRECT! Start with actual element
// max will correctly become -1
Algorithm 4: Find Minimum
int[] arr = {23, 45, 12, 67, 34};
int min = arr[0];
for (int i = 1; i < arr.length; i++)
{
if (arr[i] < min) // Just change > to <
{
min = arr[i];
}
}
System.out.println(min); // 12
Algorithm 5: Count Occurrences
int[] arr = {5, 3, 5, 7, 5, 2, 5};
int target = 5;
int count = 0;
for (int num : arr)
{
if (num == target)
{
count++;
}
}
System.out.println(count); // 4
Algorithm 6: Count Elements Meeting Condition
int[] arr = {12, 7, 25, 3, 18, 9};
// Count even numbers
int evenCount = 0;
for (int num : arr)
{
if (num % 2 == 0)
{
evenCount++;
}
}
System.out.println(evenCount); // 3 (12, 18, and implicitly checking others)
// Count numbers greater than 10
int bigCount = 0;
for (int num : arr)
{
if (num > 10)
{
bigCount++;
}
}
System.out.println(bigCount); // 3 (12, 25, 18)
Algorithm 7: Check if Any Element Meets Condition
int[] arr = {12, 7, 25, 3, 18};
// Check if any element is negative
boolean hasNegative = false;
for (int num : arr)
{
if (num < 0)
{
hasNegative = true;
// Can break here for efficiency, but not required
}
}
System.out.println(hasNegative); // false
Algorithm 8: Check if ALL Elements Meet Condition
int[] arr = {12, 8, 24, 6, 18};
// Check if ALL elements are even
boolean allEven = true; // Assume true, look for counterexample
for (int num : arr)
{
if (num % 2 != 0) // If any is NOT even
{
allEven = false;
}
}
System.out.println(allEven); // true
Algorithm 9: Shift Elements Left
int[] arr = {1, 2, 3, 4, 5};
// Shift all elements left by one position
// First element is lost, last position gets default/placeholder
for (int i = 0; i < arr.length - 1; i++)
{
arr[i] = arr[i + 1];
}
arr[arr.length - 1] = 0; // Or some default value
// arr = [2, 3, 4, 5, 0]
Algorithm 10: Shift Elements Right
int[] arr = {1, 2, 3, 4, 5};
// Shift all elements right by one position
// Last element is lost, first position gets new value
for (int i = arr.length - 1; i > 0; i--) // Go backward!
{
arr[i] = arr[i - 1];
}
arr[0] = 99; // New value at front
// arr = [99, 1, 2, 3, 4]
Algorithm 11: Reverse an Array
int[] arr = {1, 2, 3, 4, 5};
// Swap elements from outside in
for (int i = 0; i < arr.length / 2; i++)
{
// Swap arr[i] with arr[length - 1 - i]
int temp = arr[i];
arr[i] = arr[arr.length - 1 - i];
arr[arr.length - 1 - i] = temp;
}
// arr = [5, 4, 3, 2, 1]
// Trace for arr = [1, 2, 3, 4, 5]:
// i=0: swap arr[0] and arr[4] → [5, 2, 3, 4, 1]
// i=1: swap arr[1] and arr[3] → [5, 4, 3, 2, 1]
// i=2: 2 is NOT < 5/2=2, so loop ends
Algorithm 12: Copy Array
int[] original = {1, 2, 3, 4, 5};
// Create new array and copy elements
int[] copy = new int[original.length];
for (int i = 0; i < original.length; i++)
{
copy[i] = original[i];
}
// Now copy is independent of original
copy[0] = 99;
// copy = [99, 2, 3, 4, 5]
// original = [1, 2, 3, 4, 5] (unchanged)
int[] a = {1, 2, 3};
int[] b = a; // b points to SAME array as a!
b[0] = 99;
System.out.println(a[0]); // 99! a was also changed!
This creates an alias, not a copy. Both variables point to the same array.
Using Text Files NEW for 2025-2026
The College Board added file I/O to the curriculum! You'll use the File and Scanner classes to read data from text files.
Basic File Reading Pattern
import java.io.File;
import java.io.IOException;
import java.util.Scanner;
public class FileDemo
{
public static void main(String[] args) throws IOException
{
// Step 1: Create File object
File myFile = new File("data.txt");
// Step 2: Create Scanner to read from file
Scanner input = new Scanner(myFile);
// Step 3: Read data using a loop
while (input.hasNext())
{
String line = input.nextLine();
System.out.println(line);
}
// Step 4: Close the scanner
input.close();
}
}
Any method that reads from a file must include throws IOException in its header. This tells Java that file operations might fail (file not found, permission denied, etc.).
Scanner Methods for Reading Files
| Method | Returns | Description |
|---|---|---|
hasNext() |
boolean |
Returns true if there's more data to read |
nextLine() |
String |
Reads and returns the entire next line |
next() |
String |
Reads and returns the next word (token) |
nextInt() |
int |
Reads and returns the next integer |
nextDouble() |
double |
Reads and returns the next double |
Example: Reading Numbers from a File
Suppose numbers.txt contains:
10
25
30
15
40
public static void readNumbers() throws IOException
{
File file = new File("numbers.txt");
Scanner input = new Scanner(file);
int sum = 0;
int count = 0;
while (input.hasNext())
{
int num = input.nextInt();
sum += num;
count++;
}
input.close();
System.out.println("Sum: " + sum); // Sum: 120
System.out.println("Count: " + count); // Count: 5
System.out.println("Average: " + (double) sum / count); // Average: 24.0
}
Example: Reading Mixed Data Types
Suppose students.txt contains:
Alice 95 3.8
Bob 87 3.2
Carol 92 3.6
public static void readStudents() throws IOException
{
File file = new File("students.txt");
Scanner input = new Scanner(file);
while (input.hasNext())
{
String name = input.next(); // Read name (word)
int score = input.nextInt(); // Read score (integer)
double gpa = input.nextDouble(); // Read GPA (double)
System.out.println(name + ": Score=" + score + ", GPA=" + gpa);
}
input.close();
}
// Output:
// Alice: Score=95, GPA=3.8
// Bob: Score=87, GPA=3.2
// Carol: Score=92, GPA=3.6
Example: Reading File Data into an ArrayList
public static ArrayList<Integer> loadNumbers(String filename) throws IOException
{
ArrayList<Integer> numbers = new ArrayList<Integer>();
File file = new File(filename);
Scanner input = new Scanner(file);
while (input.hasNext())
{
numbers.add(input.nextInt()); // Autoboxing: int → Integer
}
input.close();
return numbers;
}
Example: Processing Each Line Separately
public static void processLines() throws IOException
{
File file = new File("data.txt");
Scanner input = new Scanner(file);
int lineNumber = 1;
while (input.hasNext())
{
String line = input.nextLine();
System.out.println("Line " + lineNumber + ": " + line);
lineNumber++;
}
input.close();
}
Expect questions that ask you to:
- Read data from a file into an array or ArrayList
- Process file data (sum, count, find max/min)
- Understand the
throws IOExceptionclause - Use
hasNext()as a loop condition
You won't need to handle exceptions with try-catch or write to files.
Wrapper Classes
ArrayLists can only hold objects, not primitive types. Wrapper classes let you wrap primitives in objects.
Primitive Types and Their Wrappers
| Primitive | Wrapper Class | Example |
|---|---|---|
int |
Integer |
Integer x = Integer.valueOf(5); |
double |
Double |
Double y = Double.valueOf(3.14); |
boolean |
Boolean |
Boolean b = Boolean.valueOf(true); |
Autoboxing: Automatic Primitive → Object
// Java automatically converts primitives to wrapper objects
Integer num = 42; // int 42 is automatically "boxed" into an Integer
Double price = 19.99; // double is boxed into Double
// Works with ArrayList too!
ArrayList<Integer> numbers = new ArrayList<Integer>();
numbers.add(10); // int 10 is autoboxed to Integer
numbers.add(20);
numbers.add(30);
Unboxing: Automatic Object → Primitive
Integer numObj = 42;
int numPrim = numObj; // Integer is automatically "unboxed" to int
// Works when getting from ArrayList
ArrayList<Integer> numbers = new ArrayList<Integer>();
numbers.add(100);
int value = numbers.get(0); // Integer is unboxed to int
int doubled = numbers.get(0) * 2; // Unboxing happens automatically
Integer num = null;
int x = num; // CRASH! Can't unbox null!
// This can happen with ArrayList too:
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(null); // Legal - ArrayList can hold null
int val = list.get(0); // CRASH! Trying to unbox null
Useful Integer Methods
// Parse a String to int
String s = "123";
int num = Integer.parseInt(s); // num = 123
// Get maximum and minimum possible int values
int maxInt = Integer.MAX_VALUE; // 2147483647
int minInt = Integer.MIN_VALUE; // -2147483648
Useful Double Methods
// Parse a String to double
String s = "3.14159";
double pi = Double.parseDouble(s); // pi = 3.14159
ArrayList
An ArrayList is a resizable array. Unlike arrays, you can add and remove elements.
Creating an ArrayList
import java.util.ArrayList;
ArrayList<String> names = new ArrayList<String>();
ArrayList<Integer> nums = new ArrayList<Integer>();
ArrayList Methods
| Method | Description |
|---|---|
add(obj) |
Add to end |
add(i, obj) |
Insert at index i |
get(i) |
Get element at i |
set(i, obj) |
Replace at i, returns old |
remove(i) |
Remove at i, returns removed |
size() |
Number of elements |
Traced Example
ArrayList<String> list = new ArrayList<String>();
list.add("A"); // [A]
list.add("B"); // [A, B]
list.add("C"); // [A, B, C]
list.add(1, "X"); // [A, X, B, C]
list.set(0, "Z"); // [Z, X, B, C]
list.remove(2); // [Z, X, C]
ArrayList Algorithms
// WRONG!
for (int i = 0; i < list.size(); i++)
if (condition) list.remove(i);
// CORRECT - go backward!
for (int i = list.size()-1; i >= 0; i--)
if (condition) list.remove(i);
Remove All Occurrences
public static void removeAll(ArrayList<String> list, String target)
{
for (int i = list.size() - 1; i >= 0; i--)
if (list.get(i).equals(target))
list.remove(i);
}
Filter to New List
public static ArrayList<Integer> getEvens(ArrayList<Integer> nums)
{
ArrayList<Integer> result = new ArrayList<Integer>();
for (int n : nums)
if (n % 2 == 0)
result.add(n);
return result;
}
² 2D Arrays
Creating 2D Arrays
int[][] grid = new int[3][4]; // 3 rows, 4 cols
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
matrix[1][2] // Row 1, Col 2 → 6
matrix.length // Rows (3)
matrix[0].length // Cols (3)
Row-Major Traversal
for (int r = 0; r < arr.length; r++)
for (int c = 0; c < arr[0].length; c++)
System.out.print(arr[r][c] + " ");
Column-Major Traversal
for (int c = 0; c < arr[0].length; c++)
for (int r = 0; r < arr.length; r++)
System.out.print(arr[r][c] + " ");
2D Array Algorithms
Sum All Elements
public static int sumAll(int[][] arr)
{
int sum = 0;
for (int r = 0; r < arr.length; r++)
for (int c = 0; c < arr[0].length; c++)
sum += arr[r][c];
return sum;
}
Count Matching
public static int countPositive(int[][] arr)
{
int count = 0;
for (int r = 0; r < arr.length; r++)
for (int c = 0; c < arr[0].length; c++)
if (arr[r][c] > 0)
count++;
return count;
}
Process Single Row
public static int rowSum(int[][] arr, int row)
{
int sum = 0;
for (int c = 0; c < arr[0].length; c++)
sum += arr[row][c];
return sum;
}
Process Single Column
public static int colSum(int[][] arr, int col)
{
int sum = 0;
for (int r = 0; r < arr.length; r++)
sum += arr[r][col];
return sum;
}
Searching Algorithms
Linear Search - Works on ANY array
public static int linearSearch(int[] arr, int target)
{
for (int i = 0; i < arr.length; i++)
if (arr[i] == target)
return i;
return -1;
}
Binary Search - REQUIRES SORTED ARRAY!
public static int binarySearch(int[] arr, int target)
{
int low = 0, high = arr.length - 1;
while (low <= high)
{
int mid = (low + high) / 2;
if (arr[mid] == target)
return mid;
else if (arr[mid] < target)
low = mid + 1;
else
high = mid - 1;
}
return -1;
}
Binary Search Trace
// arr = [10, 20, 30, 40, 50, 60, 70, 80], target = 30
// low=0, high=7, mid=3 → arr[3]=40 > 30 → high=2
// low=0, high=2, mid=1 → arr[1]=20 < 30 → low=2
// low=2, high=2, mid=2 → arr[2]=30 = 30 → Found!
| Search | Worst Case | Sorted? |
|---|---|---|
| Linear | n | No |
| Binary | log||(n) | Yes! |
Š Sorting Algorithms
Selection Sort
Find minimum, swap to front. Repeat.
public static void selectionSort(int[] arr)
{
for (int i = 0; i < arr.length - 1; i++)
{
int minIdx = i;
for (int j = i + 1; j < arr.length; j++)
if (arr[j] < arr[minIdx])
minIdx = j;
// Swap
int temp = arr[i];
arr[i] = arr[minIdx];
arr[minIdx] = temp;
}
}
Selection Sort Trace
// [64, 25, 12, 22, 11]
// Pass 1: min=11 at idx 4, swap with idx 0 → [11, 25, 12, 22, 64]
// Pass 2: min=12 at idx 2, swap with idx 1 → [11, 12, 25, 22, 64]
// Pass 3: min=22 at idx 3, swap with idx 2 → [11, 12, 22, 25, 64]
// Pass 4: min=25 at idx 3, no swap needed → [11, 12, 22, 25, 64]
Insertion Sort
Build sorted portion by inserting each element in correct position.
public static void insertionSort(int[] arr)
{
for (int i = 1; i < arr.length; i++)
{
int key = arr[i];
int j = i - 1;
while (j >= 0 && arr[j] > key)
{
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
| Sort | Best | Worst |
|---|---|---|
| Selection | n² | n² |
| Insertion | n | n² |
Recursion
A method that calls itself. Needs: base case + recursive case.
Factorial
public static int factorial(int n)
{
if (n <= 1) return 1; // Base case
return n * factorial(n - 1); // Recursive case
}
// factorial(5) = 5*4*3*2*1 = 120
Fibonacci
public static int fib(int n)
{
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
// 0, 1, 1, 2, 3, 5, 8, 13...
Recursive Binary Search
public static int binSearch(int[] arr, int t, int lo, int hi)
{
if (lo > hi) return -1;
int mid = (lo + hi) / 2;
if (arr[mid] == t) return mid;
if (arr[mid] < t) return binSearch(arr, t, mid+1, hi);
return binSearch(arr, t, lo, mid-1);
}
- Missing base case → StackOverflowError
- Not progressing toward base case
- Forgetting
returnon recursive call
Common Exam Traps
1. Off-by-One
i <= arr.length
✔
i < arr.length
2. length vs length() vs size()
| Array | arr.length |
| String | str.length() |
| ArrayList | list.size() |
3. 2D Array [row][col]
grid[col][row]
✔
grid[row][col]
4. String Comparison
str1 == str2
✔
str1.equals(str2)
5. Enhanced for Can't Modify
for (int num : arr)
num = num * 2; // Doesn't change array!
6. Initialize max to arr[0], not 0
int max = 0; // Fails for all-negative arrays
int max = arr[0]; // ✔ Correct
7. Binary Search Needs Sorted Data
int[] unsorted = {50, 10, 30};
binarySearch(unsorted, 30); // Wrong result!
Practice Questions
Q1: Array Traversal
int[] arr = {2, 4, 6, 8, 10};
int sum = 0;
for (int i = 0; i < arr.length; i += 2)
sum += arr[i];
System.out.println(sum);
Indices 0,2,4: 2+6+10=18
Q2: Enhanced For Loop
int[] arr = {1, 2, 3};
for (int num : arr)
num = num + 10;
System.out.println(arr[1]);
Enhanced for loop doesn't modify the array.
Q3: 2D Array Access
int[][] grid = {{1,2,3}, {4,5,6}, {7,8,9}};
System.out.println(grid[2][0] + grid[0][2]);
grid[2][0]=7, grid[0][2]=3, sum=10
Q4: ArrayList Operations
ArrayList<String> list = new ArrayList<String>();
list.add("A"); list.add("B"); list.add("C");
list.add(1, "X");
list.remove(2);
System.out.println(list);
After adds: [A,B,C]. Insert X at 1: [A,X,B,C]. Remove idx 2: [A,X,C]
Q5: Recursion Trace
public static int mystery(int n) {
if (n <= 0) return 0;
return 1 + mystery(n - 2);
}
System.out.println(mystery(7));
m(7)=1+m(5)=1+1+m(3)=1+1+1+m(1)=1+1+1+1+m(-1)=4+0=4
Q6: Fibonacci
public static int fib(int n) {
if (n <= 1) return n;
return fib(n-1) + fib(n-2);
}
System.out.println(fib(6));
Sequence: 0,1,1,2,3,5,8... fib(6)=8
Q7: Binary Search Comparisons
int[] arr = {10, 20, 30, 40, 50, 60, 70, 80}; // Find 30
How many comparisons to find 30 with binary search?
mid=3(40)→left, mid=1(20)→right, mid=2(30)→found
Q8: Selection Sort Pass
int[] arr = {64, 25, 12, 22, 11};
After ONE pass of selection sort:
Find min (11), swap with first element (64)
Q9: Which Search?
Array is UNSORTED with 1000 elements. Which search?
Binary search requires sorted data!
Q10: ArrayList Removal Bug
ArrayList<Integer> list = ...; // [1, 2, 3, 4]
for (int i = 0; i < list.size(); i++)
if (list.get(i) % 2 == 0)
list.remove(i);
System.out.println(list);
Forward removal bug! After removing 2, 4 shifts to index 1 but i=2, so 3 is at index 1 and gets skipped over but 4 at new position gets removed.
Q11: File I/O
Which is required when reading from a file with Scanner?
File operations may fail, so Java requires handling with throws or try-catch.
Q12: Wrapper Class
Integer x = null;
int y = x + 5;
What happens?
Can't unbox null to int.
FRQ Practice
FRQ 1: ArrayList Processing (FRQ #3 Style)
Part A: Write countAbove that returns how many scores are above a threshold.
public static int countAbove(ArrayList<Integer> scores, int threshold)
Part B: Write removeBelow that removes all scores below a passing grade.
public static void removeBelow(ArrayList<Integer> scores, int passing)
public static int countAbove(ArrayList<Integer> scores, int threshold)
{
int count = 0;
for (int score : scores)
if (score > threshold)
count++;
return count;
}
Part B:
public static void removeBelow(ArrayList<Integer> scores, int passing)
{
for (int i = scores.size() - 1; i >= 0; i--)
if (scores.get(i) < passing)
scores.remove(i);
}
Rubric (Part B - 5 pts)
+1 Traverses backward
+1 Uses get(i) correctly
+1 Compares to passing
+1 Uses remove(i)
+1 No elements skipped
FRQ 2: 2D Array Processing (FRQ #4 Style)
Part A: Write countEmpty that returns how many null elements are in a 2D String array.
public static int countEmpty(String[][] chart)
Part B: Write getColumn that returns an ArrayList of all non-null elements in a column.
public static ArrayList<String> getColumn(String[][] chart, int col)
public static int countEmpty(String[][] chart)
{
int count = 0;
for (int r = 0; r < chart.length; r++)
for (int c = 0; c < chart[0].length; c++)
if (chart[r][c] == null)
count++;
return count;
}
Part B:
public static ArrayList<String> getColumn(String[][] chart, int col)
{
ArrayList<String> result = new ArrayList<String>();
for (int r = 0; r < chart.length; r++)
if (chart[r][col] != null)
result.add(chart[r][col]);
return result;
}
Rubric (Part A - 4 pts)
+1 Nested loops
+1 Correct bounds
+1 Checks for null
+1 Returns count
FRQ 3: File I/O (NEW Topic!)
Write loadData that reads integers from a file into an ArrayList.
public static ArrayList<Integer> loadData(String filename) throws IOException
public static ArrayList<Integer> loadData(String filename) throws IOException
{
ArrayList<Integer> data = new ArrayList<Integer>();
File file = new File(filename);
Scanner input = new Scanner(file);
while (input.hasNext())
data.add(input.nextInt());
input.close();
return data;
}
Quick Reference
Essential Syntax
| Structure | Create | Access | Size |
|---|---|---|---|
| Array | new int[5] |
arr[0] |
arr.length |
| ArrayList | new ArrayList |
list.get(0) |
list.size() |
| 2D Array | new int[3][4] |
grid[r][c] |
grid.length, grid[0].length
|
Algorithm Complexity
| Algorithm | Best | Worst | Note |
|---|---|---|---|
| Linear Search | 1 | n | Any array |
| Binary Search | 1 | log n | Sorted only! |
| Selection Sort | n² | n² | |
| Insertion Sort | n | n² | Best when nearly sorted |
Final Checklist
-
<not<=for loop bounds -
.length/.length()/.size() -
grid[row][col]notgrid[col][row] - Remove from ArrayList BACKWARD
-
.equals()for Strings - Binary search = sorted only
- Initialize max/min to first element
- Enhanced for can't modify
- Check for null before method calls
-
throws IOExceptionfor files