Introduction
Arrays are collections of values. Whereas a regular variable can only hold one value at a time, an array can hold multiple values. As a comparison, this is what a regular int
variable looks like:
int x = 10;
And this is what an int
array looks like:
int[] x = {7, 356, 29, 107, 480};
Whereas x
in the first example contains only one value (10), x
in the second example contains five values (7, 256, 29, 107, 480). The square brackets ([]
) after the data type is how you declare an array variable instead of a normal one. The curly brackets ({}
) contain the values to be stored in the array, separated by commas. Values in arrays are called elements and an array can hold as few or as many elements as needed. The number of elements an array contains is called the array’s length or size (once an array is created, its size cannot be changed). Every element in an array is numbered sequentially, starting at 0. This is called the index number. The figure below shows how you can imagine array x
.

x
You access elements via their index number in square brackets. For example, x[2]
means “index 2 of array x
”, which is 29. This is what it looks like in a program:
public class Arrays1 { public static void main(String[] args) { int[] x = {7, 319, 29, 107, 480}; System.out.println(x[2]); } }
[Run] 29
Line 3 creates an int array called x
. It contains the five elements from above. Line 4 prints x[2]
(29).
In general, we can do with array elements what can be done with regular variables. See if you can follow the program below.
public class Arrays2 { public static void main(String[] args) { int[] x = {7, 319, 29, 107, 480}; System.out.println(x[3]); x[3] = 89; int a = x[0]; System.out.print(a + x[4] - x[3]); } }
[Run] 107 398
Line 3 is the same as before. Line 4 prints index 3 (107). On line 5, index 3 is reassigned (107 is overwritten by 89). Line 6 copies index 0 into variable a (x[0]
is 7 so a
is also 7). Line 7 calculates and prints a + x[4] – x[3]
, which is 7 + 480 – 89, resulting in 398.
What happens if you try accessing an index that doesn’t exist, like index 5?
public class Arrays3 { public static void main(String[] args) { int[] x = {7, 319, 29, 107, 480}; System.out.println(x[5]); } }
In this case you get an “index out of bounds” error:
[Run] Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 5 at Arrays1.main(Arrays1.java:4)
Array Types
You can create arrays of any data type. The figure below shows Regular variables and their Array counterparts, both with arbitrary values.
Type | Regular | Array |
---|---|---|
int | int v = 17; | int[] v = {17, -38, 0, 1096, 525, 17, -811, 50} |
double | double w = 23.50; | double[] w = {18.3, 0.831, 272.63, -8.9}; |
char | char x = ‘>’; | char[] x = {‘#’, ‘>’, ‘*’, ‘K’, ‘+’, ‘3’}; |
boolean | boolean y = true; | boolean[] y = {false, true, true, false, true} |
String | String z = “Hello”; | String[] z = {“Cup of Java”, “Howdy”, “vj49gt$”}; |
As you can see, arrays can hold multiple values of their respective type. All arrays use the same indexing scheme starting at 0. For example, in row five, the String array z
holds three strings, and the code z[1]
refers to the string “Howdy”. The arrays are created using an initialiser list. That is, values between curly brackets ({}
). Conversely, the figure below shows how to create the same type of arrays the classic way. The Array Definition column shows how to create arrays of different types using the new
keyword. For example, in row 1, the code new int[5]
creates an int
array with 5 elements. Like previous examples, the array is stored in a variable (v
). This variable’s type is int[]
meaning it can hold an int
array. The Default Values column shows what the array actually looks like when created in this way. Every element is given a default value depending on its type.
Type | Array Definition | Default Values |
---|---|---|
int | int[] v = new int[5]; | {0, 0, 0, 0, 0} |
double | double[] w = new double[5]; | {0.0, 0.0, 0.0, 0.0, 0.0} |
char | char[] x = new char[5]; | {‘\0’, ‘\0’, ‘\0’, ‘\0’, ‘\0’} |
boolean | boolean[] y = new boolean[5]; | {false, false, false, false, false} |
String | String[] z = new String[5]; | {null, null, null, null, null} |
Moving down the rows, we can see that the default value for an int
array is 0, a double
array is 0.0, a char
array is ‘\0’
, a boolean
array is false
, and a String
array is null
. The value null
basically means no data (‘\0’
is the char
’s equivalent of null
). We’ll look into null
a little later.
Looping Through Arrays
Often, we want to perform some action on each element in an array. For example, we may want to print each element. We could do this manually like so:
public class Arrays1 { public static void main(String[] args) { int[] x = {7, 319, 29, 107, 480}; System.out.println(x[0]); System.out.println(x[1]); System.out.println(x[2]); System.out.println(x[3]); System.out.println(x[4]); } }
[Run] 7 319 29 107 480
Lines 4-8 print out each element individually. But what if we had hundreds or thousands of elements in the array? We certainly don’t want to write thousands of print statements! This is where loops come in. We can write a loop that prints the next index on each iteration. Remember in the previous chapter how we used i
in loops to count up or down (0 to 9 for instance). Since array indexes (or indices) are also numbered, we can use i
in place of the index number to access every array element automatically. For example:
public class Arrays3 { public static void main(String[] args) { int[] x = {7, 319, 29, 107, 480}; for (int i = 0; i < 5; i++) { System.out.println(x[i]); } } }
[Run] 7 319 29 107 480
This program does the same thing as the previous one but using a loop. Lines 4-6 is a for loop. Line 4 tells us that the loop starts with i
at 0 and stops when i
is 5. This means i
will go through numbers 0, 1, 2, 3, 4. Thus, x[i]
(line 5) will give each subsequent element in the array. Just so it’s clear, let’s go through it manually:
- Line 3 creates an array of five elements.
- Line 4 is the start of the for loop. In it, variable
i
is declared and set to 0. The condition is checked (i < 5
), which is true. Line 5 printsx[i]
. Sincei
is 0, this is the same asx[0]
, so 7 is printed. i++
increasesi
(soi
= 1).i < 5
is true. Line 5 printsx[i]
(x[1]
) so 319 is printed.i++
increasesi
(soi
= 2).i < 5
is true. Line 5 printsx[i]
(x[2]
) so 29 is printed.i++
increasesi
(soi
= 3).i < 5
is true. Line 5 printsx[i]
(x[3]
) so 107 is printed.i++
increasesi
(soi
= 4).i < 5
is true. Line 5 printsx[i]
(x[4]
) so 480 is printed.i++
increasesi
(soi
= 5).i < 5
is false. The loop ends and so does the program.
The above program works but not only is it inflexible, it’s also brittle. If the array contained more than five elements, we’d have to remember to change the loop condition otherwise not all elements will be printed. Even worse, if the array contained fewer than five elements and we forgot the amend the condition then the program would crash since the loop would go out of bounds of the array. We need a way to tell the loop to repeat the same number of times as the number of elements in the array. This is actually quite easy. Arrays have an internal length
variable that keeps track of the number of elements. We can read this variable directly as demonstrated in the following program.
public class Arrays1 { public static void main(String[] args) { int[] x = {7, 319, 29, 107, 480, 54, 1833}; for (int i = 0; i < x.length; i++) { System.out.println(x[i]); } } }
The condition has been changed to i < x.length
so the loop will always repeat the appropriate number of times. I’ve added two more elements to x
making a total of seven elements. Therefore, the loop condition is basically i < 7
, ergo the loop repeats seven times printing indexes 0 to 6.
[Run] 7 319 29 107 480 54 1833
Now in Reverse
Now let’s loop through the array backwards. In order to do so, we need i
to start at the last index, decrease by 1 each iteration, and stop when it reaches index 0. For instance:
public class Arrays1 { public static void main(String[] args) { int[] x = {7, 319, 29, 107, 480, 54, 1833}; for (int i = x.length - 1; i >= 0; i--) { System.out.println(x[i]); } } }
[Run] 1833 54 480 107 29 319 7
All three parts of the for loop need to change in order to loop through the array backwards. Let’s look at the first part, int i = x.length – 1
. This tells us that i
will start at x.length – 1
, which is 7 – 1, which is 6 (the last index). Note that an array’s length minus one will always give the last index in an array, of any size. The condition i >= 0
tells us that the loop will repeat as long as i
is greater than or equal to 0. The third part i--
will decrease i
every iteration so that i
goes through 6, 5, 4, 3, 2, 1, 0. It also decreases once more to -1 but this causes the condition to be false, so the loop ends (otherwise line 5 would give an out of bounds error).
Simple Array Processing
Iterating over arrays is very useful in programming because it allows us to write common code for all elements. For example, the program below only prints elements that are greater than 100.
public class GreaterThan100 { public static void main(String[] args) { int[] x = {7, 319, 29, 107, 480, 54, 1833}; for (int i = 0; i < x.length; i++) { if (x[i] > 100) { System.out.println(x[i]); } } } }
[Run] 319 107 480 1833
As we can see, values 319, 107, 480, and 1833 are printed whereas 7, 29, and 54 are not. This is due to the if statement on line 5 that checks if x[i]
is greater than 100 and therefore only prints the number if true. Here is a rundown of the steps the program takes:
- Line 4:
int i = 0
→i < x.length
is true. - Line 5:
x[i] > 100
(7 > 100) is false. - Line 4:
i++
(i
is 1) →i < x.length
is true. - Line 5:
x[i] > 100
(319 > 100) is true. - Line 6: Print
x[i]
(319). - Line 4:
i++
(i
is 2) →i < x.length
is true. - Line 5:
x[i] > 100
(29 > 100) is false. - Line 4:
i++
(i
is 3) →i < x.length
is true. - Line 5:
x[i] > 100
(107 > 100) is true. - Line 6: Print
x[i]
(107). - And so on…
If you’re having trouble untangling the program in your head then think about it this way: At this point we can basically ignore the loop because all it does is cause i
to go from 0 to 7. So, let’s focus purely on the if statement (line 5). x[i]
is going to be x[0]
(7), then x[1]
(319), then x[2]
(29), then x[3]
(107), etc. Therefore, the if statement goes through every element in the array to see if it’s greater than 100. If true, it gets printed (line 6); if false, it doesn’t. That’s it, really. Another way to think about it is that x[i]
is like a placeholder for each element in the array, where each element is substituted one at a time.
Arrays Are Reference Types
There are two categories of (data) types: primitive types and reference types. Recall that there are only eight primitive types: byte
, short
, int
, long
, float
, double
, char
, and boolean
. All other types are reference types—these include all the reference types we’ve looked at so far such as String
, Scanner
, and DecimalFormat
, as well as arrays themselves. The key difference between the two types is that variables of primitive types contain their values directly whereas variables of reference types contain their values indirectly. What does this mean in practice? Take the following code:
int a = 5; int b = a;
First, a
is set to 5. Then, b
is set to a
. This means the value of a
gets copied into b
i.e. 5 gets copied into b
. Both a
and b
end up being 5. We can picture a
and b
like this:
![Text Box: int[] aArr = {5, 14, 11};
int[] bArr = aArr;](https://www.factiverse.com/wp-content/uploads/2020/06/ch9-primitive-types.png)
Let’s now try the same thing with arrays:
int[] c = {5, 14, 11}; int[] d = c;
Array c
contains arbitrary values 5, 14, and 11. Underneath, d
is set to c
. It’s reasonable to think that the array {5, 14, 11} gets copied into d
, so both c
and d
end up being {5, 14, 11}. But this isn’t exactly what happens because array variables do not contain arrays directly. In reality, the array {5, 14, 11} is stored in some memory location and the variable c
contains a reference to it (a reference is akin to a memory address). In other words, c
contains the location of the array, not the array itself. This means when d
is set to c
, the reference in c
is copied into d
so both variables end up referencing the same array. The following figure depicts this:

Again, what c
contains is a reference (0x5A41) to the array. When d
is set to c
, this reference is copied into d
. Therefore, both variables end up referencing the same array. This means any changes made to the array in d
will be reflected in c
and vice versa, because they are one and the same. Let’s look at a program that demonstrates this:
public class ArrayReference { public static void main(String[] args) { int[] c = {5, 14, 11}; int[] d = c; d[1] = 75; System.out.println(Arrays.toString(c)); System.out.println(Arrays.toString(d)); } }
[Run] [5, 75, 11] [5, 75, 11]
Lines 3 and 4 recreate the two arrays from the example. Then, line 6 changes index 1 in d
to 75 (originally 14). Lines 8 and 9 print out the contents of both arrays. As we can see from the output, both c
and d
show 75 even though it was only d
that was altered on line 6. Again, it’s because there’s only one array and both c
and d
hold a reference to it, so a change to one is a change to the other. And, by the way, for printing the two arrays on lines 8 and 9, I used a handy method from the Arrays
class called toString
. This method takes an array and returns a human-readable string of its contents i.e. “[5, 75, 11]”. This saves us from having to manually loop through both arrays just to print out their elements.
Multidimensional Arrays
Multidimensional arrays are arrays of more than 1 dimension. So far, we’ve only looked at 1-dimensional (1D) arrays, which can be thought of as a sequence of values.
Two-dimensional Array
A 2-dimensional array is defined by using two pairs of square brackets:
int[][] a2d = new int[4][5];
a2d
is a 4 by 5 array. 2D arrays can be imagined as a grid of values with rows and columns. By default, all values are 0 so a2d
looks like this:

2D arrays aren’t that much more complicated than 1D arrays, we just need to remember that we’re dealing with a 2D grid and not a 1D line, thus we need two pairs of square brackets instead of one. For example, the following line changes the element at [3][1] to 5:
a2d[3][1] = 5;

We can also think of 2D arrays as an array of arrays (of values). We get a good visualisation of this by creating the same 4 x 5 array using an initialiser list:
int[][] a2d = { {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} };
a2d
contains 4 arrays. Each array itself contains 5 values (all zeros). If this is unclear, here is each array highlighted:
int[][] a2d = { {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0} };
Let’s change the element at [2][2] to a different value:
a2d[2][2] = 91;
The first [2] specifies an array. The second [2] specifies a value in that array. Now a2d
looks like this:
a2d { {0, 0, 0, 0, 0}, {0, 0, 0, 0, 0}, {0, 0, 91, 0, 0}, {0, 0, 0, 0, 0} };
Remember that array indexing starts at 0 so [2][2] really means the 3rd value of the 3rd array, as illustrated in the following figure:
![Text Box: a2d[0][3] = -23;](https://www.factiverse.com/wp-content/uploads/2020/06/ch9-array-index-2-2.png)
How about changing the element at [0][3]:
a2d[0][3] = -23;
a2d { {0, 0, 0, -23, 0}, {0, 0, 0, 0, 0}, {0, 0, 91, 0, 0}, {0, 0, 0, 0, 0} };

Three-dimensional Arrays
Arrays can be of any number of dimensions—3D, 4D, 5D, 10D, etc. The more dimensions, the more square brackets. A 3D array is defined with 3 pairs of square brackets:
int[][][] a3d = new int[2][4][3];
And this is the same array created using an initialiser list:
int[][][] a3d = { { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }, { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} } };
You can imagine a 3D array as a cube of values, whereby you go along the x, y, and z axes. Or you can imagine it as an array of arrays of arrays of values (yikes). This isn’t so bad if we break it down like before by highlighting each part.
This is the whole array:
{ { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }, { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} } }
Inside are [2] arrays:
{ { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }, { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} } }
Inside are [4] arrays each:
{ { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }, { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} } }
Inside are [3] values each:
{ { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }, { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} } }
Therefore element [1][0][2], for example, refers to the element coloured in red:
{ { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} }, { {0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0} } }
Foreach Loop
A foreach loop can be used in place of a for loop when you want to loop through an array. A foreach loop simplifies the syntax and can make code easier to read. As an example, the following program uses a classic for loop to output the contents of an array.
public class ClassicForLoop { public static void main(String[] args) { double[] someArray = {25.92, 1.34, -76.24, 833.11, 76.084}; for (int i = 0; i < someArray.length; i++) { System.out.println(someArray[i]); } } }
[Run] 25.92 1.34 -76.24 833.11 76.084
Line 3 creates an array called someArray
, which contains five elements. The for loop underneath iterates over (loops through) the array, where line 6 simply prints out each element.
Now let’s do the same thing but with a foreach loop:
public class ForEachLoop { public static void main(String[] args) { double[] someArray = {25.92, 1.34, -76.24, 833.11, 76.084}; for (double e : someArray) { System.out.println(e); } } }
Here, someArray
is the array to iterate over and e
is each element in the array. A colon separates the two. You can read it as “For each e
(element) in someArray
, do whatever’s in the body”. To elaborate, e
is simply a variable. Every time the loop repeats, e
will contain the next element from someArray
. So, on the first iteration, e
is 25.92, the second iteration e
is 1.34, the third iteration e
is -76.24, and so on, until the end. On each iteration, e
is printed on line 6. A foreach loop always repeats the same number of times as the number of elements in the array, so you don’t have to worry about it going out of bounds. Furthermore, e
is a double
because that’s what the arrays contains, a set of double
s. If someArray
were a String
array, you would have to make e
a String
variable to hold each element. Also, you don’t have to call it e
, you can call it anything you like, with it being a variable and all.