Lesson 9 — Collections of Values

Arrays

An array is a fixed-size, indexed collection of values of the same type. Arrays are the simplest data structure and the foundation of all others — understanding them deeply makes everything that follows easier.

What is an Array?

An array is a contiguous block of memory divided into fixed-size slots, all of the same type. Each slot has an index, starting at 0. If you have an array of 5 marks, the valid indexes are 0, 1, 2, 3, and 4. Accessing index 5 causes an ArrayIndexOutOfBoundsException at runtime — one of the most common Java errors.

Declaring and Initialising Arrays

JAVA — Array declarations
// Style 1: declare and initialise with values
int[] marks = {65, 72, 80, 58, 91};

// Style 2: declare size, fill later (all slots initialised to 0/null/false)
String[] names = new String[4]; // 4 slots, all null
names[0] = "Thandi";
names[1] = "Sipho";
names[2] = "Lerato";
names[3] = "Bongani";

// Style 3: declare separately from new (less common)
double[] scores;
scores = new double[]{74.5, 81.0, 68.3};

System.out.println("First mark:  " + marks[0]);   // 65
System.out.println("Last mark:   " + marks[4]);    // 91
System.out.println("Array size:  " + marks.length);// 5 — NOT marks.length()

// Default values for newly allocated arrays:
int[]     intArr  = new int[3];     // {0, 0, 0}
boolean[] boolArr = new boolean[3]; // {false, false, false}
String[]  strArr  = new String[3];  // {null, null, null}

Iterating Arrays

You almost always process arrays inside a loop. Use the regular for loop when you need the index; use for-each when you only need the values.

JAVA — Iterating
int[] marks = {65, 72, 80, 58, 91};

// for loop — use when you need the index
System.out.println("--- Marks with index ---");
for (int i = 0; i < marks.length; i++) {
    System.out.println("Learner " + (i + 1) + ": " + marks[i] + "%");
}

// for-each — cleaner when you only need values
System.out.println("--- Processing marks ---");
int total = 0;
for (int mark : marks) {
    total += mark;
}
double average = (double) total / marks.length;
System.out.printf("Total: %d  |  Average: %.2f%%%n", total, average);

// Finding max and min manually
int max = marks[0];
int min = marks[0];
for (int mark : marks) {
    if (mark > max) max = mark;
    if (mark < min) min = mark;
}
System.out.println("Highest: " + max + "  Lowest: " + min);

Sorting and Searching

JAVA — Sorting and searching
import java.util.Arrays;

int[] marks = {65, 72, 80, 58, 91, 44};

// Sort ascending (modifies the array in place)
Arrays.sort(marks);
System.out.println(Arrays.toString(marks)); // [44, 58, 65, 72, 80, 91]

// Binary search (array must be sorted first)
int idx = Arrays.binarySearch(marks, 72);
System.out.println("72 found at index: " + idx); // 3

// Copy an array (not just copy the reference)
int[] copy = Arrays.copyOf(marks, marks.length);
int[] partial = Arrays.copyOfRange(marks, 1, 4); // indexes 1,2,3

2D Arrays (Tables)

A 2D array is an array of arrays — useful for grids, tables, matrices, and spreadsheet-like data.

JAVA — 2D arrays
// 2D array: 3 learners, 4 assessment marks each
int[][] gradebook = {
    {75, 82, 68, 91},   // Learner 1
    {60, 55, 72, 80},   // Learner 2
    {90, 88, 95, 87}    // Learner 3
};

// Access: gradebook[row][column]
System.out.println("Learner 2, Assessment 3: " + gradebook[1][2]); // 72

// Iterate with nested loops
for (int row = 0; row < gradebook.length; row++) {
    System.out.print("Learner " + (row + 1) + ": ");
    int rowTotal = 0;
    for (int col = 0; col < gradebook[row].length; col++) {
        System.out.printf("%3d ", gradebook[row][col]);
        rowTotal += gradebook[row][col];
    }
    System.out.printf("| Avg: %.1f%n", (double) rowTotal / gradebook[row].length);
}

Common Array Patterns

JAVA — Common patterns
// Count elements matching a condition
int[] marks = {65, 72, 80, 58, 91, 44, 77, 69};
int passCount = 0;
for (int mark : marks) {
    if (mark >= 50) passCount++;
}
System.out.println("Pass rate: " + passCount + "/" + marks.length);

// Reverse an array
for (int i = 0; i < marks.length / 2; i++) {
    int temp = marks[i];
    marks[i] = marks[marks.length - 1 - i];
    marks[marks.length - 1 - i] = temp;
}
System.out.println(Arrays.toString(marks));

// Fill an array with a value
int[] zeros = new int[5];
Arrays.fill(zeros, -1); // {-1, -1, -1, -1, -1}

Practice Task

Your Turn

Create an integer array of 8 learner marks. Write code that: (1) calculates and prints the mean, (2) counts how many marks are above the mean, (3) prints the highest and lowest without using Arrays.sort, (4) sorts the array and prints it, (5) creates a new array containing only the marks that are 60 or above (you'll need to count them first to allocate the right size).

Common Mistakes

  • Accessing marks[marks.length] — the last valid index is marks.length - 1. This is the most common Java runtime error.
  • marks.length not marks.length() — for arrays, length is a field, not a method. length() is for Strings.
  • Arrays are fixed-size — you cannot add or remove elements after creation. Use ArrayList when you need a resizable collection (Lesson 19).
  • Copying an array with =: int[] copy = original copies the reference, not the data. Both variables point to the same array. Use Arrays.copyOf().
  • Forgetting that array slots default to 0 for int, false for boolean, and null for objects — using a null String causes a NullPointerException.

Professional Tip

Master arrays thoroughly — every other collection in Java (ArrayList, HashMap, etc.) is implemented using arrays underneath. Understanding arrays makes the higher-level tools much easier to reason about.

Mini Quiz

What is the index of the last element in a Java array of length 8?