Java from the ground up

Arrays and the Arrays helper

One name for many values, indexing from zero, the length that cannot change, and the helper class that makes an array readable.

Part 7 of 12

Intermediate14 min readBack to Courses

One name, many slots

An array holds a fixed number of values of one type in numbered slots. int[] nums = {7, 3, 9, 4}; builds four ints; nums[0] is the first of them and nums[3] the last. The count lives in nums.length, read without brackets.

The size is chosen when the array is created and never changes. To read or write a slot, use an index between 0 and length minus one. Anything outside that range stops the program with an ArrayIndexOutOfBoundsException, which is Java telling you the slot does not exist.

Arrays.toString, because printing is not enough

Printing an array directly does not show its contents. It shows the type of the array followed by a code and a number where the object lives, which is useless to a reader. That is exactly why the helper class exists.

Arrays.toString(nums) hands back ordinary text: [7, 3, 9, 4]. Arrays.sort(nums) rearranges the slots into order, smallest first, and Arrays.fill or Arrays.copyOf handle the other everyday jobs. The class lives in java.util, so the file starts with an import.

Arrays and loops go together

The enhanced for walks the slots in order without an index. When you need the position — to compare one slot with the next, or to number the output — use the counted loop and index into the array with nums[i].

A new array of numbers starts as zeros, and a new array of text starts as null values, which print as the word null. Filling every slot before reading it is the habit that avoids the most common null surprise.

The name is a reference

An array variable does not hold the values directly; it holds a reference to the block of slots. int[] copy = nums; copies the reference, so both names point at one array. Change through one and the other sees it.

Arrays.copyOf(nums, nums.length) makes a second block with the same contents. That distinction — alias or copy — explains most surprises when an array seems to change by itself.

Defaults, length and two dimensions

A new array is filled with defaults: zeros for numbers, false for booleans, null for objects. An array literal fills the slots at once, which is why the examples use one. length is a field, not a method, so there are no brackets after it.

A two-dimensional array is an array of arrays. int[][] grid = new int[3][4]; gives three rows of four; grid[1][2] names one slot. Each row can have a different length, though the rectangular form is the one to start with.

Searching and filling

Arrays has a few more methods worth knowing. Arrays.fill(nums, 0) writes the same value into every slot, which is the quick way to reset a buffer. Arrays.equals(a, b) compares two arrays slot by slot, and Arrays.copyOfRange(nums, 1, 3) copies a piece: the first index is included and the second is not, the same rule as substring.

Arrays.binarySearch is the odd one. It is fast because it halves the range at each step, and it is only correct on an array that is already sorted. Search an unsorted array and the answer is meaningless: it may report not found for a value that is there, or point at the wrong slot. Sort first, then search.

Smallest, largest, total, average

Four questions come up so often that they are worth writing once. The smallest value starts at the first slot and is replaced whenever a smaller one appears; starting at zero is wrong for an array of positive numbers, because zero wins. The largest follows the same shape with the comparison reversed.

A total starts at zero and adds each slot. An average divides that total by the length, and one side of the division has to be a double or the fraction is dropped. All four are one loop with three variables, which is why the weather example below is worth reading line by line rather than skimming.

Creating, reading and sorting an array

import java.util.Arrays;

int[] nums = {7, 3, 9, 4};

System.out.println(nums.length);          // 4
System.out.println(nums[0]);              // 7
System.out.println(Arrays.toString(nums)); // [7, 3, 9, 4]

Arrays.sort(nums);
System.out.println(Arrays.toString(nums)); // [3, 4, 7, 9]

// A counted loop when the position matters.
for (int i = 0; i < nums.length; i++) {
    System.out.println(i + ": " + nums[i]);
}

A row of numbers, read and reshaped

Press Run and compare each printed line with the array at that moment. Then change a slot of your own, print the array again, and add a line that prints the array before sorting.

Output
Click "Run" to execute your code

Three array mistakes: using length as the last index (it is one past it), comparing two arrays with == instead of Arrays.equals, and assuming a fresh array of objects is filled with usable values. The last one produces a NullPointerException on the first read.

Try these next

  • Build a five-slot array of zeros, fill it with the squares of 1 to 5, and print it with Arrays.toString.
  • Copy an array with Arrays.copyOf, change one slot in the copy, and print both arrays to prove they are separate.
  • Print a 3 by 3 grid with nested loops, then change one slot and print the grid again.

A week of temperatures, summarised

Press Run and check the smallest, largest and average against the seven values. Then change one day to 25 and predict how each of the four numbers moves before you run it.

Output
Click "Run" to execute your code

An index is not a count. Four slots are numbered 0, 1, 2 and 3, so nums[4] is out of range and stops the program rather than giving an empty value.

Check what you learned

One question at a time. A wrong answer explains itself — take another go.

Part 1 of 5

Which index holds the last value of a four-item array?