Skip to content
Theory · Arrays · lesson 3 of 8

Looping over an array and Arrays

An array is rarely read one element at a time. Usually you need to do something with all its elements at once: add them up, print them, sort them.

Let's go back to the row of lockers. To check every locker, you walk along the row from the first to the last and open each one in turn. For an array, a loop takes that walk: on each lap it takes the next index. Let's add up the scores:

JAVA
public class Main {
    public static void main(String[] args) {
        int[] scores = {90, 75, 60};
        int sum = 0;
        for (int i = 0; i < scores.length; i++) {
            sum = sum + scores[i];
        }
        System.out.println(sum); // 225
    }
}

Let's walk through the program line by line:

  1. int sum = 0; sets up the sum, zero for now.
  2. for (int i = 0; i < scores.length; i++) goes through the indices 0, 1 and 2: exactly as many laps as there are elements in the array.
  3. sum = sum + scores[i]; adds the element at the current index to the sum.
  4. After the loop, System.out.println(sum) prints 225.

The index loop

This loop has three rules:

  • counting starts at 0, the first index;
  • the condition is i < scores.length, strictly less: the last index is one less than the length;
  • through the index you can change elements as well as read them: scores[i] = scores[i] * 2; doubles the current element.

With the condition i <= scores.length the loop makes one extra lap. On it i becomes 3, and reading scores[3] throws an ArrayIndexOutOfBoundsException.

The for-each loop

When you do not need the index, there is a shorter form. The for-each loop puts each element of the array into a variable in turn, from the first to the last. The same sum with it looks like this:

JAVA
int total = 0;
for (int x : scores) {
    total = total + x;
}
System.out.println(total); // 225

The header for (int x : scores) reads as "for each x in scores":

  • int x is the variable for the current element; its type matches the type of the elements;
  • the colon separates the variable from the array;
  • scores is the array the loop goes through.

There is no counter, condition or step here: the loop itself knows where the array starts and ends. So it cannot step past the end.

The variable x gets a copy of the element, the same way b in int b = a gets a copy of the number. It is an ordinary variable: you can change it, say by writing x = 0. But the array does not change because of it. It is like copying a number from a locker into a notebook: a correction in the notebook does not change what lies in the locker. So for-each is for reading elements, and to change them you need the index loop.

Imports and the Arrays class

The Java standard library is thousands of ready-made classes. They are sorted into packages, like books on shelves: each class has a full name made of the package name and its own name. The Arrays class with tools for arrays sits in the package java.util, and its full name is java.util.Arrays.

The classes System, String and Integer sit in the package java.lang. Java brings that package into every program by itself, which is why we have not had to bring in anything so far. For a class from another package, you write an import at the start of the file, before public class Main:

JAVA
import java.util.Arrays;

public class Main {
    public static void main(String[] args) {
        int[] scores = {90, 75, 60};
        System.out.println(Arrays.toString(scores)); // [90, 75, 60]
        Arrays.sort(scores);
        System.out.println(Arrays.toString(scores)); // [60, 75, 90]
    }
}

Here the shelf picture is off: an import does not take the class off the shelf or copy its code into the program. It only tells the compiler that the short name Arrays means java.util.Arrays. Without that line the compiler does not know the name Arrays and stops with the error cannot find symbol, the same one as for an undeclared variable.

Arrays.toString

Arrays.toString(scores) builds a string from the elements, in square brackets and separated by commas: [90, 75, 60]. It is handy to print when you need to see the whole array at once.

You cannot do without this method. The line System.out.println(scores) prints not the elements but a service note like [I@ followed by a mix of digits and letters. That is a code for the type and an internal number of the array, and it can change from run to run.

Arrays.sort

Arrays.sort(scores) sorts the elements in ascending order. It changes the array itself instead of creating a new one, and it returns nothing. So the call is written as a statement of its own, and you look at the result through Arrays.toString. The line System.out.println(Arrays.sort(scores)) does not compile.

Common mistake

You wanted to double all the prices and wrote the new value into the for-each variable:

JAVA
int[] prices = {10, 20, 30};
for (int p : prices) {
    p = p * 2; // ✗
}
System.out.println(Arrays.toString(prices)); // [10, 20, 30]

The program compiles and prints [10, 20, 30]: the prices did not change. Each lap doubled the copy of the element in the variable p, and the array stayed as it was. To change the elements, you need the index loop: prices[i] = prices[i] * 2;.

Key points

  • The index loop starts at 0 with the condition i < a.length; through a[i] elements can be read and changed.
  • The for-each loop for (int x : a) puts a copy of each element into x: writing to x does not change the array.
  • A class from another package is brought in with an import at the start of the file: import java.util.Arrays;.
  • Arrays.toString turns an array into the string [90, 75, 60], and Arrays.sort sorts the array itself in ascending order.