Skip to content
elephantoo

Arrays

Lesson 8 of 43 16 min read

Create, loop over, copy, sort and search arrays, plus 2D arrays and the Arrays helper class.


Imagine storing the marks of 40 students in 40 separate variables. An array solves this: one variable holding a fixed number of values of the same type, each accessed by a numeric index.

Creating arrays#

Java
// 1. Declare with a size: elements get default values
int[] scores = new int[5];            // [0, 0, 0, 0, 0]

// 2. Declare with initial values (array literal)
String[] days = {"Mon", "Tue", "Wed"};

// 3. Create with new and values (useful when passing to a method)
double[] prices = new double[]{9.99, 4.50, 12.00};

Key facts:

  • The type is written int[] ("array of int"). Java also accepts int scores[], but int[] scores is the standard style.
  • The length is fixed when the array is created. Need it to grow? Use ArrayList (see the Lists lesson).
  • New arrays are filled with default values: 0 for numbers, false for boolean, '\u0000' for char and null for objects such as String.

Reading and writing elements#

Indexes start at 0, so the last index is length - 1:

ArrayBasics.java
public class ArrayBasics {
    public static void main(String[] args) {
        int[] scores = new int[4];
        scores[0] = 90;
        scores[1] = 72;
        scores[2] = 85;
        scores[3] = scores[0] - 10;

        System.out.println("First: " + scores[0]);
        System.out.println("Length: " + scores.length);
        System.out.println("Last: " + scores[scores.length - 1]);

        String[] names = new String[2];
        System.out.println(names[0]);     // default value for objects
    }
}
Output
First: 90
Length: 4
Last: 80
null

Note that length is a field, not a method: scores.length, without parentheses (unlike String's length()).

Accessing an index outside 0..length-1 crashes at runtime:

Output
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 4 out of bounds for length 4

Looping over arrays#

Use a classic for when you need the index, and the enhanced for when you just need each value:

Loops.java
public class Loops {
    public static void main(String[] args) {
        int[] temps = {31, 28, 35, 30, 33};

        for (int i = 0; i < temps.length; i++) {
            System.out.println("Day " + (i + 1) + ": " + temps[i]);
        }

        int sum = 0, max = temps[0];
        for (int t : temps) {
            sum += t;
            if (t > max) max = t;
        }
        System.out.println("Average: " + (double) sum / temps.length);
        System.out.println("Hottest: " + max);
    }
}
Output
Day 1: 31
Day 2: 28
Day 3: 35
Day 4: 30
Day 5: 33
Average: 31.4
Hottest: 35

Sum, average, minimum, maximum and "count how many match" are the bread-and-butter array algorithms. Practise writing them by hand.

Arrays are reference types#

An array variable holds a reference to the array object. Assigning it to another variable copies the reference, not the elements:

References.java
import java.util.Arrays;

public class References {
    public static void main(String[] args) {
        int[] a = {1, 2, 3};
        int[] b = a;              // same array, two names
        b[0] = 99;
        System.out.println(Arrays.toString(a));

        int[] c = a.clone();      // real, independent copy
        c[1] = -1;
        System.out.println(Arrays.toString(a));
        System.out.println(Arrays.toString(c));

        int[] d = {99, 2, 3};
        System.out.println(a == d);               // different objects
        System.out.println(Arrays.equals(a, d));  // same contents
    }
}
Output
[99, 2, 3]
[99, 2, 3]
[99, -1, 3]
false
true

The Arrays helper class#

java.util.Arrays has ready-made methods for common jobs:

ArraysHelpers.java
import java.util.Arrays;

public class ArraysHelpers {
    public static void main(String[] args) {
        int[] nums = {42, 7, 19, 3, 25};

        System.out.println(Arrays.toString(nums));   // printable form

        Arrays.sort(nums);                           // sorts in place, ascending
        System.out.println(Arrays.toString(nums));

        int idx = Arrays.binarySearch(nums, 19);     // array must be sorted!
        System.out.println("19 is at index " + idx);

        int[] bigger = Arrays.copyOf(nums, 7);       // copy and pad with 0
        System.out.println(Arrays.toString(bigger));

        int[] middle = Arrays.copyOfRange(nums, 1, 4); // from 1 up to (not incl.) 4
        System.out.println(Arrays.toString(middle));

        int[] filled = new int[4];
        Arrays.fill(filled, 5);
        System.out.println(Arrays.toString(filled));

        String[] words = {"pear", "Apple", "banana"};
        Arrays.sort(words);                          // uppercase sorts before lowercase
        System.out.println(Arrays.toString(words));
        System.out.println(Arrays.stream(nums).sum());
    }
}
Output
[42, 7, 19, 3, 25]
[3, 7, 19, 25, 42]
19 is at index 2
[3, 7, 19, 25, 42, 0, 0]
[7, 19, 25]
[5, 5, 5, 5]
[Apple, banana, pear]
96

Arrays.stream(...) opens the door to the Streams API, which you will learn in the advanced module.

Arrays and methods#

Arrays can be passed to and returned from methods:

ArrayMethods.java
import java.util.Arrays;

public class ArrayMethods {
    static int[] reversed(int[] input) {
        int[] out = new int[input.length];
        for (int i = 0; i < input.length; i++) {
            out[i] = input[input.length - 1 - i];
        }
        return out;
    }

    static void doubleInPlace(int[] arr) {
        for (int i = 0; i < arr.length; i++) {
            arr[i] *= 2;
        }
    }

    public static void main(String[] args) {
        int[] data = {1, 2, 3, 4};
        System.out.println(Arrays.toString(reversed(data)));
        doubleInPlace(data);
        System.out.println(Arrays.toString(data));
    }
}
Output
[4, 3, 2, 1]
[2, 4, 6, 8]

Because the method receives a copy of the reference, doubleInPlace modifies the caller's array. Returning a new array, as reversed does, is usually safer and easier to reason about.

Two-dimensional arrays#

A 2D array is an array of arrays, perfect for grids, tables and game boards:

Matrix.java
public class Matrix {
    public static void main(String[] args) {
        int[][] grid = {
            {1, 2, 3},
            {4, 5, 6}
        };
        System.out.println("Rows: " + grid.length);
        System.out.println("Cols: " + grid[0].length);
        System.out.println("Middle of row 1: " + grid[1][1]);

        for (int r = 0; r < grid.length; r++) {
            for (int c = 0; c < grid[r].length; c++) {
                System.out.print(grid[r][c] + " ");
            }
            System.out.println();
        }

        char[][] board = new char[3][3];     // 3x3, filled with '\u0000'
        board[1][1] = 'X';
        System.out.println(java.util.Arrays.deepToString(new int[2][3]));

        int[][] jagged = new int[3][];       // rows can have different lengths
        jagged[0] = new int[]{1};
        jagged[1] = new int[]{1, 1};
        jagged[2] = new int[]{1, 2, 1};
        System.out.println(java.util.Arrays.deepToString(jagged));
    }
}
Output
Rows: 2
Cols: 3
Middle of row 1: 5
1 2 3
4 5 6
[[0, 0, 0], [0, 0, 0]]
[[1], [1, 1], [1, 2, 1]]

Read grid[r][c] as "row r, column c". Use Arrays.deepToString to print nested arrays.

LinearSearch.java
public class LinearSearch {
    static int indexOf(String[] items, String target) {
        for (int i = 0; i < items.length; i++) {
            if (items[i].equals(target)) {
                return i;
            }
        }
        return -1;   // conventional "not found" value
    }

    public static void main(String[] args) {
        String[] fruits = {"apple", "mango", "kiwi"};
        System.out.println(indexOf(fruits, "kiwi"));
        System.out.println(indexOf(fruits, "grape"));
    }
}
Output
2
-1

Linear search checks every element, so it takes time proportional to the array length. On a sorted array, Arrays.binarySearch halves the search space on every step and is dramatically faster for big arrays.

Arrays vs ArrayList#

ArrayArrayList
Sizefixed at creationgrows and shrinks
Element typesprimitives or objectsobjects only (Integer, not int)
Syntaxa[i], a.lengthlist.get(i), list.size()
Speed / memoryslightly leanervery close in practice

In day-to-day application code, Lists are more common. Arrays still matter for performance-critical code, main(String[] args), varargs, and interviews.

Common mistakes#

  • ArrayIndexOutOfBoundsException from using <= instead of < in the loop condition.
  • Printing an array directly ([I@1b6d3586) instead of using Arrays.toString.
  • Comparing arrays with == instead of Arrays.equals.
  • Thinking b = a copies the array.
  • Calling Arrays.binarySearch on an unsorted array: the result is undefined.

What's next#

You can now store and process collections of values. Next we explore the most used type in Java, String, and its fast, mutable partner StringBuilder.

Check your understanding

Quick quiz

0/3 answered
  1. 1.What is the last valid index of int[] a = new int[5];?

  2. 2.What does System.out.println(new int[]{1, 2, 3}); print?

  3. 3.After int[] a = {1, 2, 3}; int[] b = a; b[0] = 9;, what is a[0]?

Finished reading?

Mark this lesson complete to track your progress.