Skip to main content

5.1 Introduction to Arrays

When programming, there are situations where many variables are needed to store grades, names, dates, and more. Arrays are used to efficiently manage large numbers of such variables.

1. Why Arrays Are Necessary

Suppose you want to store the scores of 100 students.

// Without arrays, using only variables looks like this...
int score1 = 85;
int score2 = 90;
int score3 = 78;
// ... declare up to score100?? Nearly impossible.

With an array, you can manage variables of the same type as a single bundle.

// Store 100 scores in one line with an array!
int[] scores = new int[100];

// Batch processing with a loop
for (int i = 0; i < scores.length; i++) {
scores[i] = 80 + i % 20; // example score assignment
}

Key characteristics of arrays:

  • Stores multiple variables of the same type as a single unit
  • Each piece of data is called an element
  • Elements are stored contiguously in memory
  • Each element is accessed by an index(starting at 0)

2. Arrays and Memory Structure

In Java, arrays are treated as objects, unlike primitive data.

[Stack Area]         [Heap Area]

score ──────────→ [ 0 ][ 0 ][ 0 ][ 0 ][ 0 ]
(reference var) index: 0 1 2 3 4
  • Stack: The reference variable score is stored here. It holds the address (reference value) of the array on the heap.
  • Heap: The actual array data is stored in a contiguous block of memory.
int[] score = new int[5];

// The score variable itself is a reference variable on the stack
// The actual array created by new int[5] exists on the heap
System.out.println(score); // [I@7ef88735 (prints the memory address of the array)

3. Array Declaration

// Method 1: [] after the type (recommended)
int[] score;
String[] name;
double[] prices;
boolean[] flags;

// Method 2: [] after the variable name (C-style, not recommended)
int score[];
String name[];
Declaration Alone Is Not Enough

int[] score; only creates space for the reference variable. Since no actual array exists yet, using score[0] will throw a NullPointerException.

4. Array Creation

Use the new keyword with a size to create the actual array in heap memory.

int[] score;         // declaration
score = new int[5]; // create an int array of size 5

// Declaration and creation are usually done together
int[] score = new int[5];

5. Default Values

When an array is created, each element is automatically initialized to the default value for its type.

TypeDefault Value
byte, short, int, long0
float, double0.0
char'\u0000' (null character)
booleanfalse
Reference types (String, objects, etc.)null
int[] intArr = new int[3];
double[] dblArr = new double[3];
boolean[] boolArr = new boolean[3];
String[] strArr = new String[3];

System.out.println(intArr[0]); // 0
System.out.println(dblArr[0]); // 0.0
System.out.println(boolArr[0]); // false
System.out.println(strArr[0]); // null

6. Array Initialization

You can initialize an array directly with values of your choice.

// Method 1: new keyword + listed values
int[] score = new int[]{ 50, 60, 70, 80, 90 };

// Method 2: Shorthand (only possible during declaration)
int[] score = { 50, 60, 70, 80, 90 };

// Method 3: Assign one by one using indices
int[] score = new int[5];
score[0] = 50;
score[1] = 60;
// ...

// Note: when initializing later after declaration, new cannot be omitted
int[] score;
score = new int[]{ 50, 60, 70, 80, 90 }; // OK
// score = { 50, 60, 70 }; // Compile error!

7. Array Length

int[] score = { 50, 60, 70, 80, 90 };

System.out.println("Array length: " + score.length); // 5

// Indices run from 0 to (length-1)
for (int i = 0; i < score.length; i++) {
System.out.println("score[" + i + "] = " + score[i]);
}
Array Length Cannot Be Changed

In Java, the length of an array cannot be changed after creation. If a larger array is needed, you must create a new array and copy the data. If you need a dynamically changing size, use ArrayList.

8. ArrayIndexOutOfBoundsException

The valid index range is 0 through length - 1. Going outside this range causes a runtime error.

int[] arr = new int[3]; // indices: 0, 1, 2

arr[0] = 10; // OK
arr[1] = 20; // OK
arr[2] = 30; // OK
// arr[3] = 40; // ArrayIndexOutOfBoundsException!
// arr[-1] = 5; // ArrayIndexOutOfBoundsException!

// Always check bounds for safe access
int index = 5;
if (index >= 0 && index < arr.length) {
System.out.println(arr[index]);
} else {
System.out.println("Invalid index: " + index);
}

9. Four Ways to Iterate Over an Array

import java.util.Arrays;

int[] numbers = {30, 10, 50, 20, 40};

// Method 1: Traditional for loop (can access indices)
System.out.println("Method 1 - for loop:");
for (int i = 0; i < numbers.length; i++) {
System.out.print(numbers[i] + " ");
}

// Method 2: Enhanced for loop (concise, when index is not needed)
System.out.println("\nMethod 2 - enhanced for:");
for (int num : numbers) {
System.out.print(num + " ");
}

// Method 3: Arrays.toString() (quick check)
System.out.println("\nMethod 3 - Arrays.toString():");
System.out.println(Arrays.toString(numbers)); // [30, 10, 50, 20, 40]

// Method 4: Stream (Java 8+, functional style)
System.out.println("Method 4 - Stream:");
Arrays.stream(numbers).forEach(n -> System.out.print(n + " "));

10. Copying Arrays

Since array length is fixed, copying is needed when a larger array is required.

Caution: Reference Copy vs Value Copy

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

// Reference copy (both point to the same array) — caution!
int[] ref = original;
ref[0] = 99;
System.out.println(original[0]); // 99 — original was also changed!

// Value copy (true copy)
int[] copy = original.clone();
copy[0] = 100;
System.out.println(original[0]); // 99 — original is unchanged

Four Array Copying Methods

import java.util.Arrays;

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

// Method 1: for loop
int[] copy1 = new int[src.length];
for (int i = 0; i < src.length; i++) {
copy1[i] = src[i];
}

// Method 2: System.arraycopy() — fastest
int[] copy2 = new int[src.length];
System.arraycopy(src, 0, copy2, 0, src.length);
// arraycopy(source, srcStart, dest, destStart, length)

// Method 3: Arrays.copyOf() — can adjust length
int[] copy3 = Arrays.copyOf(src, src.length); // same length
int[] copy4 = Arrays.copyOf(src, 8); // larger array (rest filled with 0)

// Method 4: clone() — simple 1D array copy
int[] copy5 = src.clone();

System.out.println(Arrays.toString(copy3)); // [1, 2, 3, 4, 5]
System.out.println(Arrays.toString(copy4)); // [1, 2, 3, 4, 5, 0, 0, 0]

11. Varargs and Arrays

Using ... in a method parameter lets you receive a variable number of arguments just like an array.

public class VarargsExample {
// int... numbers is internally identical to int[] numbers
static int sum(int... numbers) {
int total = 0;
for (int n : numbers) {
total += n;
}
return total;
}

static void printAll(String... messages) {
for (String msg : messages) {
System.out.println(msg);
}
}

public static void main(String[] args) {
System.out.println(sum(1, 2, 3)); // 6
System.out.println(sum(1, 2, 3, 4, 5)); // 15
System.out.println(sum()); // 0 (zero arguments also works)

printAll("Hello", "Hi", "Bonjour");
}
}

12. Arrays as Method Arguments and Return Values

public class ArrayMethodExample {
// Method that accepts an array argument
static int getMax(int[] arr) {
int max = arr[0];
for (int i = 1; i < arr.length; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}

// Method that returns an array
static int[] createRange(int start, int end) {
int[] result = new int[end - start + 1];
for (int i = 0; i < result.length; i++) {
result[i] = start + i;
}
return result;
}

public static void main(String[] args) {
int[] scores = {85, 92, 78, 96, 88};
System.out.println("Highest score: " + getMax(scores)); // 96

int[] range = createRange(1, 5);
System.out.println(Arrays.toString(range)); // [1, 2, 3, 4, 5]
}
}

13. Practical Example: Student Score Statistics Calculator

A complete example using arrays.

import java.util.Arrays;

public class ScoreStatistics {
public static void main(String[] args) {
int[] scores = {85, 92, 78, 96, 88, 73, 61, 99, 84, 90};
int n = scores.length;

// Calculate max, min, and total
int max = scores[0];
int min = scores[0];
int sum = 0;

for (int score : scores) {
if (score > max) max = score;
if (score < min) min = score;
sum += score;
}

double average = (double) sum / n;

// Sort (clone first to preserve the original)
int[] sorted = scores.clone();
Arrays.sort(sorted);

// Calculate median
double median;
if (n % 2 == 0) {
median = (sorted[n / 2 - 1] + sorted[n / 2]) / 2.0;
} else {
median = sorted[n / 2];
}

// Print results
System.out.println("=== Student Score Statistics ===");
System.out.println("Scores: " + Arrays.toString(scores));
System.out.println("Sorted: " + Arrays.toString(sorted));
System.out.printf("Highest: %d%n", max);
System.out.printf("Lowest: %d%n", min);
System.out.printf("Total: %d%n", sum);
System.out.printf("Average: %.1f%n", average);
System.out.printf("Median: %.1f%n", median);

// Grade distribution
System.out.println("\nGrade distribution:");
int[] gradeCounts = new int[5]; // A, B, C, D, F
for (int score : scores) {
if (score >= 90) gradeCounts[0]++;
else if (score >= 80) gradeCounts[1]++;
else if (score >= 70) gradeCounts[2]++;
else if (score >= 60) gradeCounts[3]++;
else gradeCounts[4]++;
}

String[] grades = {"A (90+)", "B (80~89)", "C (70~79)", "D (60~69)", "F (~59)"};
for (int i = 0; i < grades.length; i++) {
System.out.printf("%-12s: %d student(s)%n", grades[i], gradeCounts[i]);
}
}
}

Output:

=== Student Score Statistics ===
Scores: [85, 92, 78, 96, 88, 73, 61, 99, 84, 90]
Sorted: [61, 73, 78, 84, 85, 88, 90, 92, 96, 99]
Highest: 99
Lowest: 61
Total: 846
Average: 84.6
Median: 86.5

Grade distribution:
A (90+) : 4 student(s)
B (80~89) : 3 student(s)
C (70~79) : 2 student(s)
D (60~69) : 1 student(s)
F (~59) : 0 student(s)
Pro Tips

Array vs ArrayList Selection Guide:

  • When the size is fixed and you are working with primitive types (int, double, etc.): arrays are faster and more memory-efficient
  • When the size changes dynamically or you need various collection APIs: use ArrayList<Integer>
// Array: fixed size, memory-efficient
int[] arr = new int[10];

// ArrayList: dynamic size, rich set of methods
import java.util.ArrayList;
ArrayList<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.remove(0); // dynamic resizing possible