Skip to content

05 · Arrays & Basic Collections

Arrays

An array is a fixed-size, ordered block of elements of the same type.

// Declare and initialize
int[] numbers = {10, 20, 30, 40};

// Declare with a size, fill later
String[] names = new String[3];
names[0] = "Alice";
names[1] = "Bob";
names[2] = "Cara";

System.out.println(numbers[0]);      // 10
System.out.println(numbers.length);  // 4  -- length is a field, not a method

Iterating arrays

int[] scores = {90, 85, 77, 100};

// Classic indexed loop
for (int i = 0; i < scores.length; i++) {
    System.out.println("Index " + i + ": " + scores[i]);
}

// Enhanced for-each loop
for (int score : scores) {
    System.out.println(score);
}

2D arrays

int[][] grid = {
    {1, 2, 3},
    {4, 5, 6}
};

System.out.println(grid[1][2]);   // 6 -- row 1, column 2

for (int[] row : grid) {
    for (int value : row) {
        System.out.print(value + " ");
    }
    System.out.println();
}

Common array utilities

import java.util.Arrays;

int[] nums = {5, 3, 8, 1};

Arrays.sort(nums);
System.out.println(Arrays.toString(nums));   // [1, 3, 5, 8]

int[] copy = Arrays.copyOf(nums, nums.length);

Arrays are fixed-size — once created, you can't add or remove elements, only overwrite existing slots. For dynamic sizing, use ArrayList.

ArrayList — a resizable list

ArrayList<T> is part of the Collections Framework (covered in depth in Level 2) and grows or shrinks as you add or remove elements. It holds objects, so primitives are auto-boxed (see Module 2).

import java.util.ArrayList;
import java.util.List;

List<String> todos = new ArrayList<>();

todos.add("Buy milk");
todos.add("Write report");
todos.add("Call Sam");

System.out.println(todos);              // [Buy milk, Write report, Call Sam]
System.out.println(todos.get(0));        // Buy milk
System.out.println(todos.size());        // 3

todos.remove("Call Sam");                 // remove by value
todos.remove(0);                           // remove by index -- careful, overload!
System.out.println(todos);               // [Write report]

todos.add("Write report");
for (String todo : todos) {
    System.out.println("- " + todo);
}

List of numbers (boxed)

List<Integer> scores = new ArrayList<>();
scores.add(95);
scores.add(80);

int sum = 0;
for (int score : scores) {   // auto-unboxed on each iteration
    sum += score;
}
System.out.println(sum);   // 175
Feature Array ArrayList
Size Fixed at creation Grows/shrinks dynamically
Element type Primitives or objects Objects only (auto-boxing for primitives)
Syntax arr[i] list.get(i)
Declared as int[] arr List<Integer> list

How It Actually Works

A Java array is a genuine, contiguous, fixed-length memory block with a hidden length field baked into the object header alongside the mark word and klass pointer — that's why array.length is a field access (arraylength opcode), not a method call, and O(1) regardless of size. Element access compiles to iaload/aaload plus an implicit bounds check the JVM inserts on every access; the JIT can often eliminate repeated bounds checks inside a loop once it proves the index stays within [0, length) (range-check elimination), which is a big chunk of why array loops are fast.

Arrays are also covariant but not truly type-safe at the array level: Object[] os = new String[3]; compiles fine, but writing a non-String into os throws ArrayStoreException at runtime because every array carries its actual component type and the JVM checks it on every reference-type store (aastore), not just at creation.

ArrayList wraps a plain Object[] internally. Growth is not "infinite" — it reallocates to oldCapacity + (oldCapacity >> 1) (1.5x) and System.arraycopys (a JVM intrinsic, often a single vectorized memcpy) the old contents into the new backing array, which is why appending is amortized O(1) but occasionally O(n) on a resize.

🔀 See this in another language

Exercise

Write a program that stores five student names in an ArrayList<String> and five corresponding scores in an int[] array. Print each name alongside its score using an indexed loop, then compute and print the average score. Finally add one more student to the ArrayList and print the updated size.