Matheion

MA-JAVA0 · Module 10

Collections preview, arrays of objects, and null

Topics: ArrayList · Arrays of objects · null · Null checks

Overview

Session 10 — Collections preview, arrays of objects, and null

You will contrast fixed T[] arrays with ArrayList<E>, store objects in arrays, and treat null as “no object here” — including why calling a method on a null reference crashes. This mirrors the syllabus topic arrays of objects and the null value.

Time: about 75 minutes.

Concepts

1. From fixed arrays to growable lists

int[] cannot change length. java.util.ArrayList<E> stores references in a resizable backing array, doubling capacity as needed—amortised near-constant-time append at the end.

Declare with concrete type parameter:

import java.util.ArrayList;

ArrayList<String> lines = new ArrayList<>();
lines.add("first");
lines.add("second");

Diamond operator new ArrayList<>() lets the compiler infer String from the left-hand side.


2. Generics headline

Generics (<String>) give compile-time checks: you cannot add(42) into ArrayList<String> without a compile error. At runtime, generics undergo type erasure—the JVM sees raw lists but the compiler already blocked mistakes.

Wildcards (? extends, ? super) are treated in session 18; session 17 deepens named type parameters and bounds on your own APIs.


3. Core list operations

  • add(E value) appends.
  • size() counts elements (method, unlike array .length).
  • get(int index) reads by index.
  • set(int index, E value) replaces.
  • remove(int index) or remove(Object o)—know which overload you call.

4. Iteration

Enhanced for works:

for (String line : lines) {
    System.out.println(line);
}

Traditional indexed loop still valid when index matters.


5. Arrays of objects

An array whose element type is a class stores references, not the objects themselves:

Student[] group = new Student[3];
// group[0], group[1], group[2] are all null until assigned
group[0] = new Student("Ada");
group[1] = new Student("Lin");
// group[2] still null

Loop carefully — for-each still visits null slots:

for (Student s : group) {
    if (s != null) {
        System.out.println(s.name);
    }
}

This is the usual “arrays of objects and the null value” topic after you have classes (Session 6).


6. Null discipline

null means no object. Calling a method on it throws NullPointerException.

ArrayList may also contain null entries if you add them. Decide policy:

  • Reject nulls at insertion time.
  • Filter nulls before processing (Objects.requireNonNull).
  • Leave slots null in a fixed Student[] until filled — then always check before use.

Optional (since Java 8) models “maybe absent” more explicitly—preview usage:

String firstOrNull(ArrayList<String> data) {
    if (data.isEmpty()) {
        return null;
    }
    return data.get(0);
}

Later courses show Optional chaining; here simply acknowledge null as a deliberate signal.


7. Converting to arrays

lines.toArray(new String[0]) yields a String[] snapshot—useful for legacy APIs.


8. Pitfalls

  • Autoboxing with ArrayList<int> is illegal—use Integer or IntStream patterns later.
  • Modifying a list while iterating with enhanced-for can throw ConcurrentModificationException—use iterator remove or collect changes first.

Examples

Example A — arrays of objects and null slots

public class Cohort {
    static class Student {
        String name;
        Student(String name) {
            this.name = name;
        }
    }

    public static void main(String[] args) {
        Student[] group = new Student[3];
        group[0] = new Student("Ada");
        group[1] = new Student("Lin");
        // group[2] remains null

        for (int i = 0; i < group.length; i++) {
            if (group[i] == null) {
                System.out.println("seat " + i + " empty");
            } else {
                System.out.println("seat " + i + ": " + group[i].name);
            }
        }
    }
}

After new Student[3], every slot is null until you assign. Calling group[2].name without a check crashes.


Example B — token log (ArrayList)

import java.util.ArrayList;

public class TokenLog {
    public static void main(String[] args) {
        ArrayList<String> tokens = new ArrayList<>();
        tokens.add("alpha");
        tokens.add("beta");
        tokens.add("gamma");
        System.out.println(tokens.size()); // 3
        for (String t : tokens) {
            System.out.println(t.toUpperCase());
        }
        tokens.remove(1); // removes beta
        System.out.println(tokens); // calls AbstractCollection.toString
    }
}

println on lists relies on toString implementations—handy for debugging.


Example C — guarding null inserts

public static void safeAdd(ArrayList<String> sink, String maybe) {
    if (maybe == null) {
        throw new IllegalArgumentException("null token rejected");
    }
    sink.add(maybe);
}

Fail fast at boundaries so downstream loops stay simple.


Example D — array of objects and for-each + toString

public class ProductRow {
    public static void main(String[] args) {
        Product[] products = new Product[3];

        products[0] = new Product("Cereal", 5, 250.0);
        products[1] = new Product("Milk", 8, 120.0);
        products[2] = new Product("Bread", 3, 90.0);

        for (Product p : products) {
            System.out.println(p);
        }

        // 3a — empty the second product's stock (index 1); fields are private
        products[1].setQuantity(0);
        products[1].setInStock(false);
        System.out.println("After emptying the second product:");
        System.out.println(products[1]);
    }
}

Expected output from the for-each loop (each line comes from toString()):

name: Cereal
quantity: 5
price: 250.0
inStock: false
name: Milk
quantity: 8
price: 120.0
inStock: false
name: Bread
quantity: 3
price: 90.0
inStock: false

After setQuantity(0) and setInStock(false) on products[1]:

name: Milk
quantity: 0
price: 120.0
inStock: false

products[1] is the second product (index 1). You cannot write products[1].price = 0 when price is private — use setQuantity and setInStock.

Practice check — collections preview, arrays of objects, and null

Multiple-choice check from the Matheion app lesson. Pick an answer for each question, then submit.

  1. 1.Why is `ArrayList<int> nums = new ArrayList<>();` illegal?

  2. 2.After `Student[] seats = new Student[2];` with no assignments, what is `seats[0]`?

  3. 3.Why does `System.out.println(seats[0].name);` crash right after `new Student[2]`?

  4. 4.After `list.add("a"); list.add("b"); list.remove(0);` on an `ArrayList<String>`, what is `get(0)`?

  5. 5.How does `ArrayList.size()` differ from `array.length`?