An array is a collection of values of the same data type. We store/access elements from the array by using the subscripts. Subscripts represent the positions in the array where storing and accessing can be performed. The subscripts start at 0, and the last position is size-1. The reason why is size – 1 is because we start counting at 0.
Traditional: use the following formula to define an array of any data type
<data type> [ ] <id> = new <data type>[<int–representing size>];
<data type>: can be any 8 primitive data type or Object, e.g., String. Notice that the data type on the left side of the = sign must match the data type on the right side of the = sign.
[]: is the identifier that you will handle an array
<id>: is the name of the array, use camel case style
[int]: this will represent the total size of your array
Shortcut: When you know the elements that you would like to store in an array, you can use the following format:
<data type> [ ] <id> = {e1, e2, e3, …, en};
Where e1 is the first element to store, e2 is the second element to store, and so on. Notice that all the elements must be the same data type.
For example, the following theArray holds 5 ints:
numbers held 3 1 8 6 7
Array indexes 0 1 2 3 4
When you know the exact position of the element you want to access, you must specify the position inside the [] of the array:
theArray[pos], where pos is an integer between 0 – n-1
Printing the elements of the array is not as trivial as it sounds. For example, try to print the array theArray as follows:
System.out.println( theArray );
What do you expect?
A line of numbers separated by a comma? E.g., 4,18,86,42,9,222
A line of numbers separated by space? E.g., 4 18 86 42 9 222
A concatenation of all the numbers? E.g., 41886429222
Error?
Something else?
But instead, you got something like:
By printing, we obtained an output similar to the following:
[I@42242ea4
Representing the hexadecimal memory address location where the array is located. It means that the memory is holding an array ([) of integers (I) that is located at (@) memory location (42242ea4). Meanwhile, to process the elements that are inside the array, we will need to do it independently. For example, by printing all the five elements of the array, we need to:
System.out.println(array [0]);
System.out.println(array [1]);
System.out.println(array [2]);
System.out.println(array [3]);
System.out.println(array [4]);
These statements will print the values stored from positions 0 – 4, i.e., 3, 1, 8, 6, 7
By using the shortcut, you can also represent the statements in the following:
int [] theArray = {3, 1, 8, 6, 7};
and by using the power of looping, we can simplify our previous code with the following loop:
for(int i = 0; i < 5; i++)
System.out.println(theArray [i]);
Suppose that someone forgot to provide you with two more elements to store in the array. Using the shortcut is very easy; you can simply add the two elements at the end of the array as follows:
int [] theArray = {3, 1, 8, 6, 7, 13, -1};
However, that will cause you to modify your code of printing to:
for(int i = 0; i < 7; i++)
System.out.println(theArray [i]);
This was easy; however, we cannot afford to keep modifying our code that prints the elements every time the user changes the size of the array. We need an identifier that tells us how big is the size of the array. This is called the length of the array.
The array has an immutable field called length. The length is an integer representing the total capacity of the array. In our previous example, the capacity is 5, and the way to extract that value is by calling the length of the array a, as follows: a.length.
It is called immutable because once you define an array with a specific size, you cannot change it.
So in our example, you can fix the problem of keep adding and modifying the code by using the following
for(int i = 0; i < theArray.length; i++)
System.out.println(theArray [i]);
Notice that the accessible positions of the array are from 0 to a.length-1, and therefore, you need to be very careful in accessing elements that belong in that specific range. If you go “out of the bounds” of the array, Java will complain through something called:
java.lang.ArrayIndexOutOfBoundsException
For example, if we attempt to print:
System.out.println(theArray [-1]);
Or in the original array that contains five elements, the following:
System.out.println(theArray [5]);
Both will produce the ArrayIndexOutOfBoundsException. Checking the boundaries of the array is critical to avoid what is considered to be a buffer underflow/buffer overflow.
So far, we have been writing programs that request information from the computer user and store it in multiple variables and then process the variables to compute specific tasks. As we write more complex programs, we need to store the values provided into a “data base”, primarily because we will need the values eventually to perform additional operations.
In theory: we can use variables for each value we would like to process,
The problem: is that when we may have “a lot” of values, it is almost impossible to define a variable for each value.
Solution: is to define an array of the same data type that will store a specific number of variables in a compact form.
Notice that the loops are the “BBF” (Best Friend Forever) of the arrays. Mainly because most of the time, your programs will have to navigate through the array either to print, process data, find, add or remove data. Every time these operations are performed, then you need to start from position 0 (int i = 0), all the way until you reach the end of the array (i < array.length), and you need to process the subscripts one-by-one (i++). The body of the loop will depend on whatever the task is in the first place. But the skeleton will always be the same:
for(int i =0; i < array.length; i++){
// body of the loop
}
We have discussed how to define “regular arrays”, and we noticed that they are very useful for storing information. However, we can expand the dimension of the regular arrays to further dimensions to consider relationships between more than one dimension; these are called multi-dimensional arrays. In particular, we will discuss in detail two-dimensional arrays.
We will follow the same idea of single-dimensional arrays.
<data_type>[][] <id> = new <data_type>[rows][columns];
Notice that we introduce another set of square brackets [] specifying that we are going to use a two-dimensional array.
The notion of dimension may seem confusing, but in reality, the 2D array is only a relationship between two variables. Often this is called a matrix, and probably you remember that from your math class, where you solved a linear system with matrices by using addition, subtraction, and multiplication.
An array of arrays
We are interested in visualizing the 2D array in code, so what exactly is a two-dimensional array in code? If we pay attention to the definition of an array, before the [], we specify the data type. An array containing arrays of ints can be visualized as int[][]; in other words, a two-dimensional array is an array of arrays.
How do you print the array?
System.out.println(a);
[[I@9df9bb7
[[I@9df9bb7
[[I@9df9bb7
[[I@9df9bb7
System.out.println(a[i]);
[I@4241ff45
[I@1baf605d
[I@786b5131
[I@610938fb
If we plan to print the array that we declared just by itself, we will find a representation as follows:
[[I@10bbeae3
We knew that for many chapters; however, notice that printing a two-dimensional array is similar to a typewriter. A typewriter is used to type consecutive characters on a piece of paper in a horizontal form. Every time there is a keystroke, a mechanism makes the cylindrical roller advance one position at a time. When the typewriter is close to arriving at the end of the paper’s column, it moves to the next row (sometimes using a lever).
Similarly, when printing a two-dimensional array, for every row that we process, we need to process all the columns. a.length extracts the number of rows. The a[i] access the array a at position i, by using the a[i].length, will extract the size of the internal length of the array, also known as the columns.
That is why we need nesting loops to access information from the arrays in memory.
for(int i = 0; i < a.length; i++){
for(int j = 0; j < a[i].length; j++){
System.out.print(a[i][j]+"\t");
}
System.out.println();
}
Methods that take 2D array as parameters examples:
public static void print(int[][] a){
for(int i = 0; i < a.length; i++){
for(int j = 0; j < a[i].length; j++){
System.out.print(a[i][j]+"\t");
}
System.out.println();
}
}
public static int[][] populateArray(int r, int c){
int[][] a = new int[r][c];
for(int i = 0; i < r; i++){
for(int j = 0; j < c; j++){
a[i][j] = (int)(Math.random()*16);
}
}
return a;
}